From a74b3c7127574d554599a41f5ea5f25bcb545df1 Mon Sep 17 00:00:00 2001 From: zqlit Date: Sun, 4 Oct 2026 08:45:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BD=92=E6=A1=A3=20artalk-cf=20=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E5=90=8E=E7=AB=AF=20+=20rss-robot=20=E5=88=B0=20blog-?= =?UTF-8?q?admin=EF=BC=88=E5=90=AB=E6=8A=80=E6=9C=AF=E9=80=89=E5=9E=8B/?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=88=86=E5=B8=83=20README=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blog-admin/.dev.vars.example | 5 + blog-admin/.gitignore | 16 + blog-admin/README.md | 364 ++++ blog-admin/package-lock.json | 1538 +++++++++++++++++ blog-admin/package.json | 21 + blog-admin/public/admin/admin.css | 550 ++++++ blog-admin/public/admin/admin.js | 1298 ++++++++++++++ blog-admin/public/admin/index.html | 98 ++ blog-admin/public/dist/Artalk.css | 1 + blog-admin/public/dist/Artalk.js | 11 + blog-admin/public/dist/ArtalkLite.css | 1 + blog-admin/public/dist/ArtalkLite.js | 11 + blog-admin/public/dist/i18n/jp.js | 1 + blog-admin/public/dist/i18n/zh-TW.js | 1 + .../public/dist/plugins/artalk-plugin-auth.js | 2 + blog-admin/public/feed.html | 487 ++++++ .../2a294e013c0b52bd2e00588f385a0755.jpg | Bin 0 -> 171274 bytes .../53272f92dbcb4cfd8dc9804c73206036.jpg | Bin 0 -> 40147 bytes .../874fc9aa7211aaf9ec77fb884fbf1a44.jpg | Bin 0 -> 106534 bytes .../88d9715bf6c5a539966d06e101851d02.jpg | Bin 0 -> 434318 bytes .../b1fb0164f2a567a4822401bac0426763.jpg | Bin 0 -> 349339 bytes .../b300a24e47ed3d2f326a8b1ae3458e0e.jpg | Bin 0 -> 145035 bytes .../jiege/微信图片_20260422102237_9295_4.jpg | Bin 0 -> 37144 bytes blog-admin/public/index-login.html | 34 + blog-admin/public/index.html | 45 + blog-admin/public/login.html | 48 + .../public/sidebar/assets/index-DWDx-G2X.js | 61 + .../public/sidebar/assets/index-DZ-EIihu.css | 1 + blog-admin/public/sidebar/index.html | 14 + blog-admin/public/sidebar/robots.txt | 2 + blog-admin/schema.sql | 139 ++ blog-admin/src/index.ts | 184 ++ blog-admin/src/lib/admin-notify.ts | 85 + blog-admin/src/lib/cook.ts | 256 +++ blog-admin/src/lib/db.ts | 368 ++++ blog-admin/src/lib/errors.ts | 93 + blog-admin/src/lib/human.ts | 170 ++ blog-admin/src/lib/mail.ts | 443 +++++ blog-admin/src/lib/md.ts | 220 +++ blog-admin/src/lib/md5.ts | 89 + blog-admin/src/lib/rss/cron.ts | 406 +++++ blog-admin/src/lib/rss/discover.ts | 51 + blog-admin/src/lib/rss/fetch.ts | 152 ++ blog-admin/src/lib/rss/greetings.ts | 85 + blog-admin/src/lib/rss/notify.ts | 67 + blog-admin/src/lib/rss/parse.ts | 208 +++ blog-admin/src/lib/rss/proxy-health.ts | 93 + blog-admin/src/lib/rss/util.ts | 46 + blog-admin/src/lib/session.ts | 210 +++ blog-admin/src/lib/util.ts | 140 ++ blog-admin/src/router.ts | 173 ++ blog-admin/src/routes/admin.ts | 1202 +++++++++++++ blog-admin/src/routes/comments.ts | 585 +++++++ blog-admin/src/routes/human.ts | 103 ++ blog-admin/src/routes/public.ts | 419 +++++ blog-admin/src/routes/rss/feeds.ts | 76 + blog-admin/src/routes/rss/greeting.ts | 151 ++ blog-admin/src/routes/rss/links.ts | 262 +++ blog-admin/src/routes/rss/media.ts | 170 ++ blog-admin/src/routes/rss/misc.ts | 90 + blog-admin/src/routes/rss/results.ts | 63 + blog-admin/src/routes/rss/tools.ts | 404 +++++ blog-admin/src/routes/rss/wechat.ts | 196 +++ blog-admin/src/routes/user.ts | 255 +++ blog-admin/src/rss-api.ts | 109 ++ blog-admin/src/template.generated.ts | 5 + blog-admin/src/types.ts | 196 +++ blog-admin/tools/check-artalk-human.mjs | 68 + blog-admin/tools/check-card-selfheal.mjs | 66 + blog-admin/tools/check-circles.mjs | 53 + blog-admin/tools/check-comment-error.mjs | 143 ++ blog-admin/tools/check-copyright.mjs | 40 + blog-admin/tools/check-editor-off.mjs | 74 + blog-admin/tools/check-footer-gap.mjs | 58 + blog-admin/tools/check-hr-gap.mjs | 71 + blog-admin/tools/check-human-demo.mjs | 69 + blog-admin/tools/check-human-widget.mjs | 93 + blog-admin/tools/check-list-height.mjs | 67 + blog-admin/tools/check-modal.mjs | 58 + blog-admin/tools/check-typewriter.mjs | 48 + blog-admin/tools/deploy.sh | 114 ++ blog-admin/tools/gen_template.py | 22 + blog-admin/tools/human-demo-server.mjs | 46 + blog-admin/tools/import_artrans.py | 319 ++++ blog-admin/tools/import_delta.py | 388 +++++ blog-admin/tools/mailtest.ts | 80 + blog-admin/tools/measure-badges.mjs | 209 +++ blog-admin/tools/preview-mail.ts | 57 + blog-admin/tools/probe-bottom.mjs | 51 + blog-admin/tools/probe-editor-detail.mjs | 67 + blog-admin/tools/seed-config.yaml | 64 + blog-admin/tools/selftest.ts | 117 ++ blog-admin/tools/shot-light.mjs | 45 + blog-admin/tools/smoke.sh | 68 + blog-admin/tools/test-human.mjs | 110 ++ blog-admin/tsconfig.json | 16 + blog-admin/wrangler.toml | 114 ++ blog-admin/部署清单.md | 288 +++ 98 files changed, 15657 insertions(+) create mode 100644 blog-admin/.dev.vars.example create mode 100644 blog-admin/.gitignore create mode 100644 blog-admin/README.md create mode 100644 blog-admin/package-lock.json create mode 100644 blog-admin/package.json create mode 100644 blog-admin/public/admin/admin.css create mode 100644 blog-admin/public/admin/admin.js create mode 100644 blog-admin/public/admin/index.html create mode 100644 blog-admin/public/dist/Artalk.css create mode 100644 blog-admin/public/dist/Artalk.js create mode 100644 blog-admin/public/dist/ArtalkLite.css create mode 100644 blog-admin/public/dist/ArtalkLite.js create mode 100644 blog-admin/public/dist/i18n/jp.js create mode 100644 blog-admin/public/dist/i18n/zh-TW.js create mode 100644 blog-admin/public/dist/plugins/artalk-plugin-auth.js create mode 100644 blog-admin/public/feed.html create mode 100644 blog-admin/public/images/jiege/2a294e013c0b52bd2e00588f385a0755.jpg create mode 100644 blog-admin/public/images/jiege/53272f92dbcb4cfd8dc9804c73206036.jpg create mode 100644 blog-admin/public/images/jiege/874fc9aa7211aaf9ec77fb884fbf1a44.jpg create mode 100644 blog-admin/public/images/jiege/88d9715bf6c5a539966d06e101851d02.jpg create mode 100644 blog-admin/public/images/jiege/b1fb0164f2a567a4822401bac0426763.jpg create mode 100644 blog-admin/public/images/jiege/b300a24e47ed3d2f326a8b1ae3458e0e.jpg create mode 100644 blog-admin/public/images/jiege/微信图片_20260422102237_9295_4.jpg create mode 100644 blog-admin/public/index-login.html create mode 100644 blog-admin/public/index.html create mode 100644 blog-admin/public/login.html create mode 100644 blog-admin/public/sidebar/assets/index-DWDx-G2X.js create mode 100644 blog-admin/public/sidebar/assets/index-DZ-EIihu.css create mode 100644 blog-admin/public/sidebar/index.html create mode 100644 blog-admin/public/sidebar/robots.txt create mode 100644 blog-admin/schema.sql create mode 100644 blog-admin/src/index.ts create mode 100644 blog-admin/src/lib/admin-notify.ts create mode 100644 blog-admin/src/lib/cook.ts create mode 100644 blog-admin/src/lib/db.ts create mode 100644 blog-admin/src/lib/errors.ts create mode 100644 blog-admin/src/lib/human.ts create mode 100644 blog-admin/src/lib/mail.ts create mode 100644 blog-admin/src/lib/md.ts create mode 100644 blog-admin/src/lib/md5.ts create mode 100644 blog-admin/src/lib/rss/cron.ts create mode 100644 blog-admin/src/lib/rss/discover.ts create mode 100644 blog-admin/src/lib/rss/fetch.ts create mode 100644 blog-admin/src/lib/rss/greetings.ts create mode 100644 blog-admin/src/lib/rss/notify.ts create mode 100644 blog-admin/src/lib/rss/parse.ts create mode 100644 blog-admin/src/lib/rss/proxy-health.ts create mode 100644 blog-admin/src/lib/rss/util.ts create mode 100644 blog-admin/src/lib/session.ts create mode 100644 blog-admin/src/lib/util.ts create mode 100644 blog-admin/src/router.ts create mode 100644 blog-admin/src/routes/admin.ts create mode 100644 blog-admin/src/routes/comments.ts create mode 100644 blog-admin/src/routes/human.ts create mode 100644 blog-admin/src/routes/public.ts create mode 100644 blog-admin/src/routes/rss/feeds.ts create mode 100644 blog-admin/src/routes/rss/greeting.ts create mode 100644 blog-admin/src/routes/rss/links.ts create mode 100644 blog-admin/src/routes/rss/media.ts create mode 100644 blog-admin/src/routes/rss/misc.ts create mode 100644 blog-admin/src/routes/rss/results.ts create mode 100644 blog-admin/src/routes/rss/tools.ts create mode 100644 blog-admin/src/routes/rss/wechat.ts create mode 100644 blog-admin/src/routes/user.ts create mode 100644 blog-admin/src/rss-api.ts create mode 100644 blog-admin/src/template.generated.ts create mode 100644 blog-admin/src/types.ts create mode 100644 blog-admin/tools/check-artalk-human.mjs create mode 100644 blog-admin/tools/check-card-selfheal.mjs create mode 100644 blog-admin/tools/check-circles.mjs create mode 100644 blog-admin/tools/check-comment-error.mjs create mode 100644 blog-admin/tools/check-copyright.mjs create mode 100644 blog-admin/tools/check-editor-off.mjs create mode 100644 blog-admin/tools/check-footer-gap.mjs create mode 100644 blog-admin/tools/check-hr-gap.mjs create mode 100644 blog-admin/tools/check-human-demo.mjs create mode 100644 blog-admin/tools/check-human-widget.mjs create mode 100644 blog-admin/tools/check-list-height.mjs create mode 100644 blog-admin/tools/check-modal.mjs create mode 100644 blog-admin/tools/check-typewriter.mjs create mode 100644 blog-admin/tools/deploy.sh create mode 100644 blog-admin/tools/gen_template.py create mode 100644 blog-admin/tools/human-demo-server.mjs create mode 100644 blog-admin/tools/import_artrans.py create mode 100644 blog-admin/tools/import_delta.py create mode 100644 blog-admin/tools/mailtest.ts create mode 100644 blog-admin/tools/measure-badges.mjs create mode 100644 blog-admin/tools/preview-mail.ts create mode 100644 blog-admin/tools/probe-bottom.mjs create mode 100644 blog-admin/tools/probe-editor-detail.mjs create mode 100644 blog-admin/tools/seed-config.yaml create mode 100644 blog-admin/tools/selftest.ts create mode 100644 blog-admin/tools/shot-light.mjs create mode 100644 blog-admin/tools/smoke.sh create mode 100644 blog-admin/tools/test-human.mjs create mode 100644 blog-admin/tsconfig.json create mode 100644 blog-admin/wrangler.toml create mode 100644 blog-admin/部署清单.md diff --git a/blog-admin/.dev.vars.example b/blog-admin/.dev.vars.example new file mode 100644 index 00000000..d2486418 --- /dev/null +++ b/blog-admin/.dev.vars.example @@ -0,0 +1,5 @@ +# 本地开发用:cp .dev.vars.example .dev.vars 然后改掉值 +# .dev.vars 已在 .gitignore 里,不会被提交 + +TOKEN_SECRET="local-dev-secret-please-change-me-to-something-long" +ADMIN_PASSWORD="local-dev-password" diff --git a/blog-admin/.gitignore b/blog-admin/.gitignore new file mode 100644 index 00000000..a0c49463 --- /dev/null +++ b/blog-admin/.gitignore @@ -0,0 +1,16 @@ +# 依赖与构建产物 +node_modules/ +.wrangler/ +.selftest-build/ +*.log + +# 机密(本地开发用,不提交) +.dev.vars + +# 数据迁移产物(含真实评论/用户邮箱,勿提交) +tools/import-out/ +tools/delta-out/ +tools/mail-preview/ + +# 无头浏览器测量截图 +tools/*.png diff --git a/blog-admin/README.md b/blog-admin/README.md new file mode 100644 index 00000000..293b5118 --- /dev/null +++ b/blog-admin/README.md @@ -0,0 +1,364 @@ +# artalk-cf —— 跑在 Cloudflare 上的 Artalk 评论后端 + RSS 订阅机器人 + +自研的 **Artalk API v2 兼容服务端**,以及合并进来的 **RSS 订阅机器人(rss-robot)**, +一起跑在 **Cloudflare Workers + D1 + KV** 上,零服务器、零运维、免费额度内。 + +> **状态:已上线** → `https://api.200181.xyz` +> D1 `artalk-cf`(`78140776-2bfd-439a-8b05-c3eebe5d5b47`)| KV `RSS_KV`(`d7f86a0fb43f4450a10b786fc2635128`) +> 管理员账号 `admin`(后台登录用邮箱+密码,见「部署」) +> +> **两个后台都可用**:`/admin/` 自研管理面板 | `/sidebar/` 官方 Artalk 后台 +> **评论前端一行不用改**:继续用官方 Artalk 客户端(博客里打包的 2.8.7),换后端只改 `hugo.toml` 一行 `server`。 + +--- + +## 目录 + +1. [这个项目是什么](#这个项目是什么) +2. [技术选型](#技术选型) +3. [模块分布](#模块分布) +4. [数据模型](#数据模型) +5. [部署](#部署) +6. [接到博客上](#接到博客上) +7. [评论数据迁移](#评论数据迁移) +8. [性能与免费额度](#性能与免费额度) + +--- + +## 这个项目是什么 + +两件事,各对应一个原本独立的仓库,现在合并进同一个 Worker: + +| 子项目 | 来源 | 职责 | 路径 | +|---|---|---|---| +| **artalk-cf** | 自研 | Artalk API v2 兼容评论后端(44 路径 / 54 操作已实现 46 个) | `/api/v2/*` | +| **rss-robot** | 迁移自 EdgeOne 的 `api/*.js` | RSS 订阅抓取 + 友链/友圈 + 公众号内容 | `/api/*`(不含 `/api/v2`) | + +两者共存于一个 Worker、一个 D1、一个 KV,互不冲突: +Artalk 客户端只打 `/api/v2/*`,RSS 模块只打 `/api/*`(非 v2),路径天然隔离。 + +--- + +## 技术选型 + +### 整体判断:为什么是 Cloudflare Workers + D1,而不是自建服务器 + +| 考量 | 结论 | +|---|---| +| 成本 | 免费版够用(Workers 10 万请求/天、D1 读 500 万行/天、存储 5GB),博客评论量级远用不满 | +| 运维 | 无服务器、无 SSH、无进程守护;`wrangler deploy` 一条命令发布 | +| 大陆可用性 | 见下方「已知取舍」——这是唯一的短板 | + +### 逐项选型与理由 + +**1. 运行环境:Cloudflare Workers(免费版)** + +- 全球边缘函数,`fetch` 入口 + `scheduled` 定时入口 +- **致命限制**:**没有 TCP socket** → 无法直连 SMTP 发邮件、无法跑原生 bcrypt,这两点直接决定了后续选型(见下) +- 单请求 CPU 预算约 10ms(免费版),驱动了「读写分流 + 覆盖索引 + 计数缓存」一系列优化 + +**2. 数据库:D1(Cloudflare 的 SQLite 边缘库)** + +- 兼容 SQLite 语法,`wrangler d1 execute` 直接跑 SQL,批量导入零成本 +- 读写分离:**D1 Sessions API + 只读副本**(`first-primary` 写 / `first-unconstrained` 读) +- 免费额度:读 500 万行/天、写 10 万行/天。**这是本项目最需要盯的资源**(2026-10-03 曾被打爆过一次,见性能章节的「打爆复盘」) + +**3. KV(键值存储):RSS 订阅与验证码通行证** + +- RSS 的 `feeds_config` / 抓取游标 / 失败退避、人机验证的通行证、管理员通知节流,全放 KV +- 理由:这些是「低频读、高频写、无关系」的数据,放 D1 会白白烧行数额度 + +**4. 语言:TypeScript + Wrangler** + +- 与 Workers 官方工具链天然契合;`tsc --noEmit` 做类型检查 +- 不引入任何运行时依赖(`package.json` 里只有 `@cloudflare/workers-types`、`typescript`、`wrangler` 三个 devDependencies) +- 需要原生缺失的东西就自己写:`MD5`(Gravatar hash)、`Markdown 子集解析`、`PBKDF2`(用 WebCrypto) + +**5. 鉴权:无状态 HMAC-SHA256 token + PBKDF2 密码** + +- token 用 `TOKEN_SECRET` 做 HMAC 签名、7 天过期,无状态不落库 +- 密码 PBKDF2-SHA256 12 万轮(WebCrypto 实现);兼容读取 `(md5)` 和明文(仅迁移期) +- **不用 bcrypt** 是因为 Workers 没有 Node 的 native 依赖、也不值得为一个算法引进包 + +**6. 邮件:Resend 的 HTTP API(而非 SMTP)** + +- Workers 无 TCP,SMTP 连不上;Resend 免费 3000 封/月 +- 全程 `ctx.waitUntil()` 异步 + try/catch,发信失败绝不影响评论落库 + +**7. 人机验证:自研「一键验证」(PoW + 行为信号),而非 Turnstile/reCAPTCHA** + +- 第三方脚本在大陆加载不稳定,失败会卡死评论提交;还会把访客指纹送给第三方 +- 自研版:浏览器静默算 20~80ms 的 PoW(sha256 前缀 4 个 0),命中可疑信号才让访客「点一下」,再可疑才回退图形验证码 +- 挑战无状态(HMAC 签名不写库),通行证放 KV 不占 D1 额度 + +**8. 前端:零重写,直接复用官方产物** + +- 客户端 + 官方后台(`/sidebar/`)是 Artalk v2.8.7 的预构建产物,内置在 `public/` 里 +- 自研管理面板 `/admin/` 用**纯原生 JS + 零依赖**(补齐官方后台缺的「待审视图」「关键词搜索」等) + +### 已知取舍(有意为之) + +| 项 | 取舍 | 影响 | +|---|---|---| +| 大陆 → CF 边缘 ~170ms 延迟 | CF 免费版在大陆无节点,流量被送到 LAX | 加 `` 省掉 0.5s TLS 握手,立竿见影 | +| 页面标题自动抓取 | 不做(跨境请求收益低) | 标题改为发评论时从 `page_title` 落库 | +| 邮箱验证码登录 / 社交登录 | 不做 | 管理员走密码登录,不受影响 | +| `url_resolver` | 必须保持 false | 开启会重写 page_key,现有 `/20210911.html` 全失配 | + +--- + +## 模块分布 + +``` +artalk-cf/ +├── wrangler.toml ★ Worker 配置:D1/KV/静态资源/域名/cron/变量 +├── schema.sql ★ 建表(10 张表 + 覆盖索引) +├── 部署清单.md ★ 照着敲的部署步骤(含域名那一坑) +├── .dev.vars.example 本地开发机密模板(复制成 .dev.vars) +│ +├── src/ ===== 服务端(TypeScript)===== +│ ├── index.ts 入口:路由注册 + fetch + scheduled 定时任务 +│ ├── router.ts 迷你路由器(路径参数匹配,挂 / 与 /api/v2) +│ ├── rss-api.ts RSS 模块入口(路由表 + cron 轮转抓取) +│ ├── types.ts Env / 实体 / 响应类型定义 +│ ├── template.generated.ts 设置页 YAML 模板(由官方 conf 生成) +│ │ +│ ├── lib/ ===== 通用库(无 I/O 依赖的纯逻辑)===== +│ │ ├── db.ts D1 查询封装 + 限流 + 验证码状态 +│ │ ├── cook.ts 实体 → API 输出(对应官方 dao/cook.go) +│ │ ├── session.ts token 签发/校验 + 密码 + 管理员判定 +│ │ ├── md5.ts MD5(Gravatar hash,Workers 没有) +│ │ ├── md.ts Markdown 子集 → HTML(先转义再解析,防 XSS) +│ │ ├── util.ts 时间 / CORS / 响应 / 校验工具 +│ │ ├── errors.ts ★ 统一错误出口(技术错误翻译成人话 + 机器码) +│ │ ├── human.ts 人机验证:PoW 挑战 + KV 通行证 +│ │ ├── mail.ts 邮件发送(Resend HTTP API) +│ │ ├── admin-notify.ts 管理员提醒邮件(带节流) +│ │ └── rss/ ===== RSS 订阅子系统 ===== +│ │ ├── cron.ts 每小时轮转抓取(66 源 ÷ 22 = 3 小时一轮) +│ │ ├── fetch.ts 抓取(超时/重试/代理回退/熔断) +│ │ ├── discover.ts feed 地址自动发现 +│ │ ├── parse.ts RSS/Atom 解析 +│ │ ├── greetings.ts 问候语/每日一图 +│ │ ├── notify.ts 更新推送(飞书 webhook 等) +│ │ ├── proxy-health.ts 国内代理(SCF)体检 +│ │ └── util.ts RSS 工具 +│ │ +│ └── routes/ ===== 路由处理器(按业务域分组)===== +│ ├── public.ts conf / 验证码 / 投票 / pv / setup / healthz +│ ├── comments.ts 评论 CRUD + 列表与树(含人机验证门) +│ ├── user.ts 用户 / 登录 / 合并 / SSO +│ ├── admin.ts 设置 / 站点 / 页面 / 用户 / 消息 / 统计 / 导入导出 / 上传 +│ ├── human.ts 人机验证端点(challenge / verify / status) +│ └── rss/ ===== RSS 路由 ===== +│ ├── feeds.ts 订阅源管理 +│ ├── links.ts 友链/友圈 +│ ├── results.ts 抓取结果 / 文章 +│ ├── media.ts 随机图 / 评论机器人 +│ ├── greeting.ts 问候语 +│ ├── misc.ts 鉴权 / 健康检查 +│ ├── tools.ts favicon / 代理 / cron / 部署状态 / 邮件 +│ └── wechat.ts 微信公众号内容 +│ +├── public/ 静态资源(优先级高于 Worker,改这里不用动 Worker 代码) +│ ├── index.html / 入口页(健康状态 + 两个后台入口) +│ ├── admin/ /admin/ 自研管理面板(原生 JS,6 个视图) +│ │ ├── admin.css 设计令牌 + 全部组件样式 +│ │ ├── admin.js 仪表盘/评论/页面/用户/设置/状态 +│ │ └── fonts/ Press Start 2P + JetBrains Mono +│ ├── sidebar/ /sidebar/ 官方 v2.8.7 管理后台(Vue 预构建) +│ ├── dist/ 官方 v2.8.7 客户端与插件 +│ └── feed.html /feed/ RSS 订阅源管理页 +│ +└── tools/ 工具脚本(开发/部署/自检) + ├── deploy.sh 一键部署 + ├── import_artrans.py .artrans → D1 SQL(批量迁移) + ├── import_delta.py 增量导入 + ├── gen_template.py 从官方 conf YAML 生成设置模板常量 + ├── selftest.ts 纯逻辑自检(MD5/时间/Markdown/密码/token/YAML) + ├── smoke.sh 冒烟测试 + ├── preview-mail.ts 邮件样张预览 + ├── mailtest.ts 发信测试 + └── check-*.mjs / probe-*.mjs / shot-*.mjs / measure-*.mjs + 无头浏览器(CDP)测量/回归脚本,调试评论前端用 +``` + +### 数据流一览 + +``` +浏览器(博客评论区 / 后台 iframe) + │ /api/v2/*(评论)/ /api/*(RSS) + ▼ +Worker fetch(src/index.ts) + ├─ /api/* 且非 /api/v2/* → rss-api.ts(RSS 子系统) + └─ 其余 → router.ts 分发到 routes/* + │ + ├─ 读请求 → D1 只读副本(first-unconstrained) + ├─ 写请求 → D1 主库(first-primary) + └─ 通行证 → KV(人机验证 / RSS 游标 / 通知节流) + │ +scheduled(cron) + ├─ 0 * * * * → RSS 轮转抓取(每小时 22 源) + └─ 17 3 * * * → 评论 GC(限流/验证码清理 + healthz 缓存刷新 + 代理体检) +``` + +--- + +## 数据模型 + +**10 张表**(`schema.sql`),时间统一存 unix 毫秒,输出时按 `Asia/Shanghai` 格式化: + +| 表 | 用途 | 关键字段 | +|---|---|---| +| `sites` | 站点 | name(唯一)、urls | +| `pages` | 页面 | key(=page_key 如 `/20210911.html`)、site_name、pv、vote | +| `users` | 用户 | name+email(唯一)、password(pbkdf2/md5/明文兼容)、徽章、头衔 | +| `comments` | 评论 | rid(父节点)、root_id(顶层祖先)、is_pending/pinned/verified、软删除 deleted_at | +| `votes` | 投票 | target_id + user_id + type 唯一 | +| `notifies` | 通知 | user_id、comment_id、is_read/is_emailed | +| `settings` | 键值配置 | key(主键)、value(frontend_conf / admin_users 等) | +| `rate_limits` | 限流 | bucket(如 `comment:1.2.3.4`)、count、expires_at | +| `captcha_passes` | 验证码通过状态 | ip(主键)、expires_at | +| `captcha_challenges` | 验证码题目 | answer_hash(只存哈希) | + +**覆盖索引**(性能关键,见下): + +- `idx_comments_page_list` — 列表 `ORDER BY is_pinned DESC, created_at DESC` 专用 +- `idx_comments_children` — 子评论 `root_id IN (...)` 专用 +- `idx_comments_site_list` — 站点级列表 + +`root_id` 语义与官方一致:顶层为 0,子孙为该顶层评论的 id。列表默认 `nested` 模式——取一页顶层,再捞回全部子孙交给前端组树。 + +--- + +## 部署 + +**完整步骤看 [`部署清单.md`](部署清单.md)**(照着敲约 10 分钟)。快速版: + +```bash +cd blog-admin && npm install +npx wrangler login +npx wrangler d1 create artalk-cf # 把返回的 database_id 填进 wrangler.toml +npx wrangler secret put TOKEN_SECRET +npx wrangler secret put ADMIN_PASSWORD +npx wrangler d1 execute artalk-cf --remote --file=./schema.sql +npx wrangler deploy +curl -X POST https:///api/v2/setup +``` + +### ★ 域名这一步有个坑,动手前先看 + +**Cloudflare Worker 的自定义域名要求「域名的 NS 托管在 Cloudflare」。** +而 `usj.cc` 的 NS 在 DNSPod(还挂着又拍云 + 腾讯云 EdgeOne 调度)——**千万不要为了评论 API 把整站 NS 搬去 Cloudflare**,会弄坏现有国内双 CDN 链路。 + +本项目用的是 **`api.200181.xyz`**(NS 本来就在 Cloudflare): + +```toml +[[routes]] +pattern = "api.200181.xyz" +custom_domain = true +``` + +`*.workers.dev` 地址在大陆基本不通,只能自测。四种域名方案取舍见 `部署清单.md` 第 9 步。 + +### 机密清单(不写进仓库) + +| Secret / 变量 | 用途 | +|---|---| +| `TOKEN_SECRET` | 登录 token 签名 | +| `ADMIN_PASSWORD` | 管理员密码 | +| `RESEND_API_KEY` | 邮件(可选) | +| `MAIL_FROM` / `MAIL_ADMIN` | 邮件发件人 / 收件人(可选) | + +--- + +## 接到博客上 + +`E:\GitHub\blog\hugo.toml`: + +```toml +[params.artalk] + server = "https://api.200181.xyz" # ← 只改这一行 + site = "优世界" # 必须与 SITE_DEFAULT 一致 +``` + +客户端调用 `${server}/api/v2/...`,`pageKey` 用 `.RelPermalink`(`/20210911.html`),与 D1 的 `page_key` 完全对应,**不需要改任何模板或前端代码**。 + +--- + +## 评论数据迁移 + +### 方式一:批量 SQL(推荐) + +Worker 逐条 INSERT 会产生几千次 D1 往返,免费版单请求 CPU 只有 10ms 容易超时,所以走 `wrangler d1 execute --file`: + +```bash +python tools/import_artrans.py # 读 .artrans,只导「优世界」,生成 SQL +bash tools/import-out/run.sh --remote +``` + +脚本做了:按 site_name 过滤、按「昵称+邮箱」重建用户、保留原始 id 与 rid 关系、rid 回填与 root_id 计算分三趟做(与导入顺序无关)、最后自检打印各表条数。 + +### 方式二:后台界面导入 + +登录 `/sidebar/` → 迁移页 → 上传 `.artrans`(小数据量可用)。 + +### ⚠️ 别踩的坑 + +- `url_resolver` 保持 false,否则 page_key 被重写,评论区变空 +- 导出里 `created_at` 为 Go 零值(`0001-01-01`)的 6 条会被兜底成当前时间 + +--- + +## 性能与免费额度 + +### 免费额度够不够(3440 条评论 / 138 篇文章) + +| 资源 | 免费额度 | 你的用量 | 结论 | +|---|---|---|---| +| Workers | 10 万请求/天 | 评论量级一天最多几千 | ✅ | +| D1 存储 | 5 GB | 评论约几 MB | ✅ | +| D1 读 | 500 万行/天 | 一次列表查询几十行 | ✅ | +| Workers CPU | 10 ms/请求 | 列表查询含 markdown 渲染,需观察 | ⚠️ | + +### 分层耗时(中国大陆网络实测) + +| 项 | 耗时 | +|---|---| +| 冷连接 TLS 握手 | ~0.51s | +| 连接复用后端到端 | ~190ms | +| 1 次 D1 查询 | 8~20ms | + +**真正的瓶颈是「大陆 → CF 边缘」这段(~170ms),不是数据库。** 改善:博客里加 ``,省掉 0.5s TLS 握手,成本最低。 + +### 打爆复盘(2026-10-03 D1 额度用尽) + +D1 免费版读额度(500 万行/天,UTC 00:00 = 北京 08:00 重置)被一次打爆,实测 525 万行。定位与修复: + +1. **取证**:CF GraphQL `d1QueriesAdaptiveGroups`(维度名是 `query`)按 `sum_rowsRead` 排序,锁定 `COUNT(*)` + `LEFT JOIN users` 是无索引全表扫 +2. **修复**: + - 三个覆盖索引(`idx_comments_page_list` / `_children` / `_site_list`) + - 计数 KV 缓存(只在增删/审核时失效) + - 列表/计数不再无谓 JOIN users + - 两个 COUNT 合并成一条 `COUNT(*) + SUM(CASE ...)` +3. **教训**:改动前**先本地预览 + 冒烟测试**,别拿线上打爆的额度再跑测试 + +### 自查方法 + +打开 看三个字段: + +- `colo` —— 请求落在哪个 CF 机房(决定 RTT) +- `region` / `primary` —— 查询由主库还是副本处理 +- `mail` —— 邮件是否已配置(`"on"`) + +--- + +## 安全 + +- 登录 token:HMAC-SHA256 签名,无状态、7 天过期;改密码写 `token_valid_from` 让旧 token 立即失效 +- 密码:PBKDF2-SHA256 12 万轮;兼容 `(md5)` / 明文(仅迁移) +- 后台接口全部走 `requireAdmin`,未登录 403 +- 评论软删除(`deleted_at`),误删可从 D1 恢复 +- CORS 白名单 + 预检处理;写接口走 D1 计数限流 +- 验证码答案只存哈希;人机验证挑战 HMAC 签名无状态 +- 顶层 fetch 兜底:任何漏网异常也带 CORS + 人话错误,不给读者甩「Failed to fetch」 diff --git a/blog-admin/package-lock.json b/blog-admin/package-lock.json new file mode 100644 index 00000000..b14699fe --- /dev/null +++ b/blog-admin/package-lock.json @@ -0,0 +1,1538 @@ +{ + "name": "artalk-cf", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "artalk-cf", + "version": "0.1.0", + "devDependencies": { + "@cloudflare/workers-types": "^4.20250109.0", + "typescript": "^5.7.0", + "wrangler": "^3.99.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.3.4", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=16.13" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.0.2", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.14", + "workerd": "^1.20250124.0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20250718.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20260702.1", + "dev": true, + "license": "MIT OR Apache-2.0" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-plugins/node-globals-polyfill": { + "version": "0.2.3", + "dev": true, + "license": "ISC", + "peerDependencies": { + "esbuild": "*" + } + }, + "node_modules/@esbuild-plugins/node-modules-polyfill": { + "version": "0.2.2", + "dev": true, + "license": "ISC", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "rollup-plugin-node-polyfills": "^0.2.1" + }, + "peerDependencies": { + "esbuild": "*" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/as-table": { + "version": "1.0.55", + "dev": true, + "license": "MIT", + "dependencies": { + "printable-characters": "^1.0.42" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "dev": true, + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/color-string": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/defu": { + "version": "6.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/exit-hook": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exsolve": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-source": { + "version": "2.0.12", + "dev": true, + "license": "Unlicense", + "dependencies": { + "data-uri-to-buffer": "^2.0.0", + "source-map": "^0.6.1" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/magic-string": { + "version": "0.25.9", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/miniflare": { + "version": "3.20250718.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "acorn": "8.14.0", + "acorn-walk": "8.3.2", + "exit-hook": "2.2.1", + "glob-to-regexp": "0.4.1", + "stoppable": "1.1.0", + "undici": "^5.28.5", + "workerd": "1.20250718.0", + "ws": "8.18.0", + "youch": "3.3.4", + "zod": "3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=16.13" + } + }, + "node_modules/mustache": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/ohash": { + "version": "2.0.12", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/printable-characters": { + "version": "1.0.42", + "dev": true, + "license": "Unlicense" + }, + "node_modules/rollup-plugin-inject": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^0.6.1", + "magic-string": "^0.25.3", + "rollup-pluginutils": "^2.8.1" + } + }, + "node_modules/rollup-plugin-node-polyfills": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rollup-plugin-inject": "^3.0.0" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.33.5", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "dev": true, + "license": "MIT" + }, + "node_modules/stacktracey": { + "version": "2.2.0", + "dev": true, + "license": "Unlicense", + "dependencies": { + "as-table": "^1.0.36", + "get-source": "^2.0.12" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "5.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/unenv": { + "version": "2.0.0-rc.14", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "exsolve": "^1.0.1", + "ohash": "^2.0.10", + "pathe": "^2.0.3", + "ufo": "^1.5.4" + } + }, + "node_modules/workerd": { + "version": "1.20250718.0", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20250718.0", + "@cloudflare/workerd-darwin-arm64": "1.20250718.0", + "@cloudflare/workerd-linux-64": "1.20250718.0", + "@cloudflare/workerd-linux-arm64": "1.20250718.0", + "@cloudflare/workerd-windows-64": "1.20250718.0" + } + }, + "node_modules/wrangler": { + "version": "3.114.17", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.3.4", + "@cloudflare/unenv-preset": "2.0.2", + "@esbuild-plugins/node-globals-polyfill": "0.2.3", + "@esbuild-plugins/node-modules-polyfill": "0.2.2", + "blake3-wasm": "2.1.5", + "esbuild": "0.17.19", + "miniflare": "3.20250718.3", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.14", + "workerd": "1.20250718.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=16.17.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2", + "sharp": "^0.33.5" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20250408.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/youch": { + "version": "3.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "cookie": "^0.7.1", + "mustache": "^4.2.0", + "stacktracey": "^2.1.8" + } + }, + "node_modules/zod": { + "version": "3.22.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/blog-admin/package.json b/blog-admin/package.json new file mode 100644 index 00000000..bdb4ceed --- /dev/null +++ b/blog-admin/package.json @@ -0,0 +1,21 @@ +{ + "name": "artalk-cf", + "version": "0.1.0", + "private": true, + "description": "Artalk API v2 compatible comment backend on Cloudflare Workers + D1", + "scripts": { + "dev": "wrangler dev", + "deploy": "wrangler deploy", + "typecheck": "tsc --noEmit", + "db:init:local": "wrangler d1 execute artalk-cf --local --file=./schema.sql", + "db:init:remote": "wrangler d1 execute artalk-cf --remote --file=./schema.sql", + "import:gen": "python tools/import_artrans.py", + "selftest": "tsc tools/selftest.ts --outDir .selftest-build --module commonjs --target es2022 --moduleResolution node --types ./node_modules/@cloudflare/workers-types --skipLibCheck --esModuleInterop --noEmit false && node .selftest-build/tools/selftest.js", + "tail": "wrangler tail" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20250109.0", + "typescript": "^5.7.0", + "wrangler": "^3.99.0" + } +} diff --git a/blog-admin/public/admin/admin.css b/blog-admin/public/admin/admin.css new file mode 100644 index 00000000..065a098f --- /dev/null +++ b/blog-admin/public/admin/admin.css @@ -0,0 +1,550 @@ +/* ========================================================================== + 评论后台样式 —— 对齐 post.usj.cc(写作后台)的视觉语言 + 色板与度量照抄 write-server/src/app/globals.css + + 原则:可读性优先 + · 暖白底 + 深蓝墨字(不是纯黑,降低长时间阅读的刺眼感) + · 1px 细边框代替投影,只有弹层才用阴影 + · 字号偏小但层级明确:11 / 12 / 13 / 15 / 22 + · 圆角克制:6px(控件)/ 8px(卡片)/ 16px(登录卡) + · 无装饰性动效,只保留 hover 的颜色过渡 + ========================================================================== */ + +/* ---------------------------------------------------------- 色板 */ +/* 参考 EWD 后台:白色侧栏 + 中性浅灰内容底 + 蓝色点缀 */ + +:root{ + color-scheme: light; + + --bg:#f5f8f6; /* 内容区底 · 带一点绿意的浅灰 */ + --surface:#edf2ee; /* 次级面 · hover / 代码底 */ + --card:#ffffff; /* 卡片 / 侧栏 · 纯白 */ + --text:#253830; /* 正文 · 深灰绿 */ + --muted:#8b9a91; /* 次要文字 */ + --line:#e3eae5; /* 分隔线 */ + --accent:#2f9e63; /* 主色 · 清新绿 */ + --accent-hover:#288a56; + --danger:#d75a4a; + --danger-hover:#c45151; + --success:#39b86f; + --warning:#c09a46; + + --on-accent:#fff; + --accent-soft:rgba(47,158,99,.09); + --accent-line:rgba(47,158,99,.20); + --danger-soft:rgba(215,90,74,.10); + --danger-line:rgba(215,90,74,.24); + --ok-soft:rgba(57,184,111,.12); + --pend-fg:#92400e; --pend-bg:#fef3c7; --pend-line:#fde68a; + --err-fg:#991b1b; --err-bg:#fee2e2; --err-line:#fecaca; + + --shadow-card:0 1px 2px rgba(24,48,36,.04); + --shadow-pop:0 12px 32px rgba(24,48,36,.16); + + --side-w:216px; + --font:"PingFang SC","Hiragino Sans GB","Microsoft YaHei",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif; +} + +/* 夜间模式:护眼向 —— 暖墨绿黑底、降对比、柔绿点缀,不用纯黑纯白 */ +:root[data-theme="dark"]{ + color-scheme: dark; + + --bg:#141916; /* 暖墨绿黑,比纯黑柔和 */ + --surface:#1d2420; /* hover / 代码底 */ + --card:#191f1b; /* 卡片 / 侧栏 */ + --text:#d6ded7; /* 正文 · 柔白(不用纯白,降低刺眼感) */ + --muted:#8fa093; /* 次要文字 · 灰绿 */ + --line:#2a332c; /* 分隔线 · 低对比 */ + --accent:#7cc9a0; /* 主色 · 柔和绿 */ + --accent-hover:#98d8b4; + --danger:#e39a8f; + --danger-hover:#f0b6ad; + --success:#8fd4a8; + --warning:#e3c98f; + + /* 柔绿底上用深墨绿字,保证可读 */ + --on-accent:#12241a; + --accent-soft:rgba(124,201,160,.12); + --accent-line:rgba(124,201,160,.28); + --danger-soft:rgba(227,154,143,.13); + --danger-line:rgba(227,154,143,.28); + --ok-soft:rgba(143,212,168,.14); + --pend-fg:#e3c98f; --pend-bg:rgba(227,201,143,.10); --pend-line:rgba(227,201,143,.26); + --err-fg:#e39a8f; --err-bg:rgba(227,154,143,.10); --err-line:rgba(227,154,143,.26); + + --shadow-card:0 1px 2px rgba(0,0,0,.20); + --shadow-pop:0 12px 32px rgba(0,0,0,.45); +} + +/* ---------------------------------------------------------- 基础 */ + +*{box-sizing:border-box} +/* 必须放最前面:.gate / .app / .modal 的 display 会盖掉 [hidden] 的 UA 样式 */ +[hidden]{display:none!important} + +html,body{margin:0;padding:0;height:100%} +body{ + background:var(--bg); + color:var(--text); + font-family:var(--font); + font-size:13px; + line-height:1.65; + -webkit-font-smoothing:antialiased; +} +h1,h2,h3,h4{margin:0;font-weight:700;line-height:1.4} +a{color:var(--accent);text-decoration:none} +a:hover{text-decoration:underline} +::selection{background:var(--accent-soft)} + +::-webkit-scrollbar{width:6px;height:6px} +::-webkit-scrollbar-track{background:transparent} +::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px} +::-webkit-scrollbar-thumb:hover{background:var(--muted)} +*:focus-visible{outline:2px solid var(--accent);outline-offset:2px} + +.px{font-size:11px;letter-spacing:.04em;color:var(--muted);text-transform:uppercase} +.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace} + +/* ---------------------------------------------------------- 按钮 */ + +.btn{ + display:inline-flex;align-items:center;justify-content:center;gap:6px; + padding:7px 12px; + font-family:inherit;font-size:12px;font-weight:500;line-height:1.4; + color:var(--text); + background:var(--card); + border:1px solid var(--line); + border-radius:6px; + cursor:pointer;white-space:nowrap; + transition:background-color .15s,color .15s,border-color .15s; +} +.btn:hover:not(:disabled){background:var(--surface);color:var(--accent);border-color:var(--accent-line)} +.btn:disabled{opacity:.45;cursor:not-allowed} +.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent);font-weight:600} +.btn.primary:hover:not(:disabled){background:var(--accent-hover);border-color:var(--accent-hover);color:var(--on-accent)} +.btn.danger:hover:not(:disabled){color:var(--danger);border-color:var(--danger-line);background:var(--danger-soft)} +.btn.tiny{padding:5px 9px;font-size:11px} +.btn.block{display:flex;width:100%;padding:9px 12px} +.btn[data-busy]{opacity:.5;pointer-events:none} + +.icon-btn{ + display:inline-flex;align-items:center;justify-content:center; + width:28px;height:28px;padding:0; + color:var(--muted);background:transparent; + border:1px solid transparent;border-radius:6px; + font-size:14px;line-height:1;cursor:pointer; + transition:background-color .15s,color .15s; +} +.icon-btn:hover{background:var(--bg);color:var(--text)} + +/* ---------------------------------------------------------- 表单 */ + +input,select,textarea{ + width:100%;padding:9px 11px; + font-family:inherit;font-size:13px;color:var(--text); + background:var(--bg); + border:1px solid var(--line);border-radius:6px; + outline:none; + transition:border-color .15s; +} +input:focus,select:focus,textarea:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px var(--accent-soft)} +input::placeholder,textarea::placeholder{color:var(--muted);opacity:.7} +textarea{resize:vertical;min-height:88px;line-height:1.7} +select{appearance:none;cursor:pointer;padding-right:28px; + background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%); + background-position:calc(100% - 15px) 50%,calc(100% - 10px) 50%; + background-size:5px 5px,5px 5px;background-repeat:no-repeat; +} + +.lbl{display:block;margin-bottom:6px;font-size:12px;font-weight:500;color:var(--text)} +.field{display:block;margin-bottom:14px} +.field-k{display:block;margin-bottom:6px;font-size:12px;font-weight:500;color:var(--text)} + +.alert{ + padding:10px 13px;margin-bottom:16px; + font-size:12px;line-height:1.6; + color:var(--err-fg);background:var(--err-bg); + border:1px solid var(--err-line);border-radius:6px; +} +.form-err{ + margin:14px 0 0;padding:10px 13px; + font-size:12px;color:var(--err-fg);background:var(--err-bg); + border:1px solid var(--err-line);border-radius:6px; +} + +/* ---------------------------------------------------------- 登录 */ + +.gate{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;background:var(--bg)} +.login-card{ + width:100%;max-width:340px;padding:32px; + background:var(--card); + border:1px solid var(--line);border-radius:16px; + box-shadow:var(--shadow-pop); +} +.login-card h1{font-size:19px;color:var(--accent)} +.login-card .sub{margin:3px 0 26px;font-size:12px;color:var(--muted)} +.login-card form{margin-top:0} +.login-card .btn{margin-top:6px} +.login-card .hint{margin:18px 0 0;font-size:11px;line-height:1.7;color:var(--muted);text-align:center} + +/* ---------------------------------------------------------- 主框架 */ + +.app{display:flex;min-height:100vh;background:var(--bg)} + +.sidebar{ + width:var(--side-w);flex:none; + display:flex;flex-direction:column; + background:var(--card); + border-right:1px solid var(--line); + position:fixed;inset:0 auto 0 0;z-index:50; +} +.side-head{ + display:flex;align-items:center;gap:10px; + padding:16px 16px 14px; + border-bottom:1px solid var(--line); +} +.logo{ + flex:none;width:30px;height:30px; + display:flex;align-items:center;justify-content:center; + background:var(--accent);color:var(--on-accent); + font-size:14px;font-weight:700;border-radius:8px; +} +.side-tt h1{font-size:14px;color:var(--text);letter-spacing:.02em} +.side-tt p{margin:0;font-size:11px;color:var(--muted)} + +.side-nav{flex:1;padding:10px;display:flex;flex-direction:column;gap:2px;overflow-y:auto} + +.tab{ + display:flex;align-items:center;gap:10px;width:100%; + padding:8px 11px; + font-family:inherit;font-size:13px;font-weight:400;text-align:left; + color:var(--text);background:transparent; + border:0;border-radius:7px;cursor:pointer; + transition:background-color .15s,color .15s; +} +.tab svg{flex:none;opacity:.75} +.tab:hover{background:var(--surface);color:var(--accent)} +.tab.on{background:var(--accent-soft);color:var(--accent);font-weight:500} +.tab.on:hover{background:var(--accent-soft);color:var(--accent)} +.tab.on svg{opacity:1} +.tab .n{ + margin-left:auto;padding:1px 6px; + font-size:10px;line-height:1.5; + background:var(--danger);color:#fff;border-radius:999px; +} +.tab.on .n{background:var(--danger);color:#fff} + +.nav-group{ + padding:12px 11px 4px; + font-size:10.5px;font-weight:600;letter-spacing:.6px; + color:var(--muted); +} +.nav-sep{height:1px;margin:6px 8px;background:var(--line)} + +.side-foot{padding:10px 12px 12px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:2px} +.sfoot-btn{ + display:flex;align-items:center;gap:9px;width:100%; + padding:7px 10px; + font-family:inherit;font-size:12px;color:var(--muted); + background:transparent;border:0;border-radius:7px;cursor:pointer; + transition:background-color .15s,color .15s; +} +.sfoot-btn:hover{background:var(--surface);color:var(--accent)} + +.main{ + flex:1;min-width:0;margin-left:var(--side-w); + display:flex;flex-direction:column; + padding:0 28px; +} + +/* 顶栏:面包屑 + 登录身份 */ +.topbar{ + position:sticky;top:0;z-index:30; + margin:0 -28px;padding:13px 28px; + display:flex;align-items:center;gap:10px; + background:var(--card); + border-bottom:1px solid var(--line); +} +.crumb{display:flex;align-items:center;gap:7px;font-size:13px} +.crumb .cg{color:var(--muted)} +.crumb .sp{color:var(--line)} +.crumb .pg{color:var(--text);font-weight:500} +.top-right{margin-left:auto} +.side-name{font-size:12px;color:var(--muted)} +#view{padding-top:22px} + +.mobile-bar{display:none} +.scrim{display:none} + +.foot{ + margin-top:auto;padding:20px 0 24px; + display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap; + font-size:11px;color:var(--muted); +} + +/* ---------------------------------------------------------- 页头 */ + +.page-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:0 0 18px} +.page-head h2{font-size:18px} +.page-head .sub{font-size:12px;color:var(--muted)} +.page-head .right{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap} + +/* ---------------------------------------------------------- 卡片 */ + +.card{ + background:var(--card); + border:1px solid var(--line);border-radius:8px; + box-shadow:var(--shadow-card); + overflow:hidden; +} +.card-head{ + display:flex;align-items:center;gap:8px; + padding:12px 16px;border-bottom:1px solid var(--line); +} +.card-head h3{font-size:13px;font-weight:700} +.card-body{padding:16px} + +/* ---------------------------------------------------------- 统计卡 */ + +.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px} +.stat{ + padding:16px;text-align:center; + background:var(--card); + border:1px solid var(--line);border-radius:8px; +} +.stat .k{font-size:11px;color:var(--muted);margin-bottom:4px} +.stat .v{font-size:22px;font-weight:700;line-height:1.3;color:var(--accent)} +.stat .x{margin-top:2px;font-size:11px;color:var(--muted)} + +.grid2{display:grid;grid-template-columns:1.3fr 1fr;gap:14px;margin-top:14px;align-items:start} + +/* ---------------------------------------------------------- 小列表 */ + +.mini{display:flex;flex-direction:column} +.mini-i{ + display:flex;align-items:baseline;gap:10px; + padding:8px 0;border-bottom:1px solid var(--line); + font-size:13px; +} +.mini-i:last-child{border-bottom:0} +.mini-i .n{flex:none;width:62px;font-size:11px;color:var(--muted);white-space:nowrap} +.mini-i .b{flex:1;min-width:0} +.mini-i .b .nm{font-weight:500} +.mini-i .b .tx{margin-left:6px;font-size:12px;color:var(--muted)} +.mini-i .c{flex:none;font-weight:500;color:var(--accent)} + +/* ---------------------------------------------------------- 标签 */ + +.tag{ + display:inline-block;padding:1px 6px; + font-size:10px;line-height:1.6;border-radius:4px; + white-space:nowrap; +} +.tag.acc{color:var(--accent);background:var(--accent-soft)} +.tag.pink{color:var(--accent);background:var(--accent-soft)} +.tag.blue{color:var(--accent);background:var(--accent-soft)} +.tag.warn{color:var(--pend-fg);background:var(--pend-bg)} +.tag.dang{color:var(--danger);background:var(--danger-soft)} +.tag.line{color:var(--muted);border:1px solid var(--line)} + +/* ---------------------------------------------------------- 评论列表 */ + +.ctool{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:14px} +.ctool .grow{flex:1;min-width:180px} +.ctool input,.ctool select{height:36px;padding-top:0;padding-bottom:0} + +.clist{display:flex;flex-direction:column;gap:8px} + +.citem{ + padding:14px 16px; + background:var(--card); + border:1px solid var(--line);border-radius:10px; + transition:border-color .15s; +} +.citem:hover{border-color:var(--accent-line)} +.citem.pend{border-left:3px solid var(--warning)} +.citem.pin{border-left:3px solid var(--accent)} +.citem.hid{opacity:.55} + +/* 头像 + 内容 横排;回复嵌套画树状线,不用 margin hack */ +.crow{display:flex;gap:12px;align-items:flex-start} +.cavatar{ + flex:none;width:38px;height:38px; + border-radius:50%;object-fit:cover; + background:var(--surface); + border:1px solid var(--line); +} +.cmain{flex:1;min-width:0} + +.chead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:5px} +.chead .nick{font-size:13px;font-weight:600} +.chead .t{margin-left:auto;font-size:11px;color:var(--muted);white-space:nowrap} + +.cbody{ + font-size:14px;line-height:1.75;color:var(--text); + word-break:break-word;white-space:pre-wrap; +} +.cbody .ph{color:var(--muted)} + +.creplies{ + margin-top:11px;padding-left:14px; + border-left:2px solid var(--line); + display:flex;flex-direction:column;gap:8px; +} +.creplies .citem{background:var(--bg);border-radius:8px} +.creplies .citem.pend{border-left-color:var(--warning)} +.creplies .citem.pin{border-left-color:var(--accent)} + +.cfoot{ + display:flex;align-items:center;gap:10px;flex-wrap:wrap; + margin-top:9px;padding-top:9px; + border-top:1px solid var(--line); + font-size:11px;color:var(--muted); +} +.cfoot a{color:var(--muted)} +.cfoot a:hover{color:var(--accent)} +.cfoot .acts{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap} + +/* ---------------------------------------------------------- 表格 */ + +.tblwrap{ + background:var(--card); + border:1px solid var(--line);border-radius:8px; + overflow-x:auto; +} +table{width:100%;border-collapse:collapse;font-size:13px;min-width:620px} +thead th{ + padding:10px 14px;text-align:left; + font-size:11px;font-weight:500;color:var(--muted); + border-bottom:1px solid var(--line);white-space:nowrap; +} +tbody td{padding:11px 14px;border-bottom:1px solid var(--line);vertical-align:middle} +tbody tr:last-child td{border-bottom:0} +tbody tr:hover{background:var(--surface)} +td.num,th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap} +td .lk{font-size:12px;color:var(--muted)} +.ell{display:block;max-width:340px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} + +/* ---------------------------------------------------------- 分页 */ + +.pager{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;margin:20px 0 4px} +.pager .info{font-size:12px;color:var(--muted)} +.pager .info b{color:var(--text);font-weight:600} + +/* ---------------------------------------------------------- 空态 / 加载 */ + +.empty{ + padding:48px 20px;text-align:center; + font-size:13px;color:var(--muted); + background:var(--card); + border:1px dashed var(--line);border-radius:8px; +} +.empty b{display:block;margin-bottom:6px;font-size:12px;color:var(--text)} + +.loading{padding:40px;text-align:center;font-size:13px;color:var(--muted)} + +/* ---------------------------------------------------------- 键值表 */ + +.kv{display:grid;grid-template-columns:auto 1fr;gap:9px 18px;margin:0;font-size:13px} +.kv dt{font-size:12px;color:var(--muted)} +.kv dd{margin:0;word-break:break-all} +.kv dd.ok{color:var(--success);font-weight:500} +.kv dd.bad{color:var(--danger)} + +pre.code{ + margin:0;padding:14px; + background:var(--surface);color:var(--text); + border:1px solid var(--line);border-radius:6px; + font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; + font-size:12px;line-height:1.7; + overflow:auto;max-height:320px;white-space:pre; +} + +textarea.code{ + display:block;margin:0;padding:14px; + background:var(--surface);color:var(--text); + border:1px solid var(--line);border-radius:6px; + font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; + font-size:12px;line-height:1.7; + white-space:pre;tab-size:2; +} +textarea.code:focus{outline:none;border-color:var(--accent)} + +/* ---------------------------------------------------------- 提示 / 模态 */ + +.toast{ + position:fixed;left:50%;bottom:24px;transform:translateX(-50%); + z-index:600;max-width:86vw; + padding:10px 16px; + font-size:13px; + color:var(--text);background:var(--card); + border:1px solid var(--line);border-radius:8px; + box-shadow:var(--shadow-pop); +} +.toast.bad{color:var(--danger);border-color:var(--danger-line)} + +.modal{ + position:fixed;inset:0;z-index:500; + display:flex;align-items:center;justify-content:center;padding:20px; + background:rgba(24,48,36,.30); + backdrop-filter:blur(2px); +} +:root[data-theme="dark"] .modal{background:rgba(0,0,0,.55)} +.modal-card{ + width:100%;max-width:520px;max-height:86vh; + display:flex;flex-direction:column; + background:var(--card); + border:1px solid var(--line);border-radius:12px; + box-shadow:var(--shadow-pop); +} +.modal-head{ + display:flex;align-items:center;gap:10px; + padding:14px 18px;border-bottom:1px solid var(--line); +} +.modal-head h3{flex:1;font-size:14px;font-weight:700} +.modal-body{padding:18px;overflow-y:auto} + +/* ---------------------------------------------------------- 响应式 */ + +@media (max-width:1000px){ + .stats{grid-template-columns:repeat(2,1fr)} + .grid2{grid-template-columns:1fr} + .main{padding:0 20px} + .topbar{margin:0 -20px;padding:13px 20px} +} + +@media (max-width:760px){ + .mobile-bar{ + display:flex;align-items:center;gap:8px; + position:sticky;top:0;z-index:40; + height:48px;padding:0 12px; + background:var(--card);border-bottom:1px solid var(--line); + } + .mobile-title{font-size:13px;font-weight:700;color:var(--accent)} + + .scrim{display:block;position:fixed;inset:0;z-index:45;background:rgba(18,30,23,.32)} + :root[data-theme="dark"] .scrim{background:rgba(0,0,0,.5)} + + .sidebar{ + width:78%;max-width:280px; + transform:translateX(-100%); + transition:transform .2s ease-out; + box-shadow:var(--shadow-pop); + } + .sidebar.open{transform:translateX(0)} + + .main{margin-left:0;padding:0 16px} + .topbar{margin:0 -16px;padding:12px 16px;top:48px} + #view{padding-top:16px} + .stats{grid-template-columns:1fr 1fr;gap:10px} + .stat{padding:13px 10px} + .stat .v{font-size:19px} + .cavatar{width:32px;height:32px} + .ell{max-width:170px} + .page-head h2{font-size:16px} + .login-card{padding:26px 22px} +} + +@media (prefers-reduced-motion:reduce){ + *{transition:none!important} +} diff --git a/blog-admin/public/admin/admin.js b/blog-admin/public/admin/admin.js new file mode 100644 index 00000000..67890bdc --- /dev/null +++ b/blog-admin/public/admin/admin.js @@ -0,0 +1,1298 @@ +/* ========================================================================== + 评论后台 —— artalk-cf 管理面板 + 纯原生 JS,零依赖。对接本服务已有的 Artalk API v2。 + ========================================================================== */ +(function () { +'use strict'; + +// ============================================================ 基础工具 + +const API = location.origin + '/api/v2'; +const RSS_API = 'https://api.200181.xyz'; +const LS_T = 'atk.token'; +const LS_U = 'atk.user'; +const LS_RSS = 'atk.rss.token'; // 订阅口令 + +const $ = (s, r = document) => r.querySelector(s); +const $$ = (s, r = document) => Array.prototype.slice.call(r.querySelectorAll(s)); + +/** HTML 转义 —— 所有来自评论/用户的数据都必须过这一层 */ +const esc = (v) => String(v == null ? '' : v).replace(/[&<>"']/g, (m) => + ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[m])); + +/** 把用户写的 HTML 评论压成安全纯文本,表情图用占位符代替 */ +function plainify(html) { + const t = String(html == null ? '' : html) + .replace(/]*>/gi, '[图]') + .replace(//gi, '\n') + .replace(/<\/(p|div|li)>/gi, '\n') + .replace(/<[^>]+>/g, ''); + return esc(t).replace(/\n{3,}/g, '\n\n').trim(); +} + +const nfmt = (n) => Number(n || 0).toLocaleString('zh-CN'); + +function qs(obj) { + const u = new URLSearchParams(); + for (const k of Object.keys(obj)) { + const v = obj[k]; + if (v !== '' && v != null) u.set(k, String(v)); + } + return u.toString(); +} + +const truncate = (s, n) => (String(s || '').length > n ? String(s).slice(0, n) + '…' : String(s || '')); + +// ============================================================ 状态 + +const state = { + tab: 'dash', + sites: [], + site: '', + me: null, + pending: 0, + c: { q: '', type: 'all', offset: 0, limit: 20, total: 0, denom: 1, rows: [], busy: false }, + p: { offset: 0, limit: 30, total: 0 }, + u: { offset: 0, limit: 30, total: 0, q: '', rows: [] }, + openReps: new Set(), +}; + +const TABS = [ + { id: 'dash', label: '仪表盘', group: '', icon: 'dash' }, + { id: 'comments', label: '评论管理', group: '内容管理', icon: 'comments' }, + { id: 'pages', label: '页面管理', group: '内容管理', icon: 'pages' }, + { id: 'users', label: '用户管理', group: '内容管理', icon: 'users' }, + { id: 'feeds', label: '订阅源', group: '订阅中心', icon: 'feeds' }, + { id: 'links', label: '友链', group: '订阅中心', icon: 'links' }, + { id: 'images', label: '图片', group: '订阅中心', icon: 'images' }, + { id: 'settings', label: '系统设置', group: '系统', icon: 'settings' }, + { id: 'status', label: '运行状态', group: '系统', icon: 'status' }, +]; + +// 16px 线性图标(stroke 继承 currentColor) +const I = (p) => + ''; +const ICONS = { + dash: I(''), + comments: I(''), + pages: I(''), + users: I(''), + feeds: I(''), + links: I(''), + images: I(''), + settings: I(''), + status: I(''), + moon: I(''), + out: I(''), +}; + +// ============================================================ HTTP + +let TOKEN = localStorage.getItem(LS_T) || ''; + +async function api(path, opt) { + opt = opt || {}; + const headers = {}; + if (opt.body !== undefined) headers['Content-Type'] = 'application/json'; + if (TOKEN) headers['Authorization'] = 'Bearer ' + TOKEN; + + let res; + try { + res = await fetch(API + path, { + method: opt.method || 'GET', + headers, + body: opt.body !== undefined ? JSON.stringify(opt.body) : undefined, + signal: opt.signal, + }); + } catch (e) { + throw new Error('网络不可达 —— 检查域名/网络后重试'); + } + + const txt = await res.text(); + let data = null; + try { data = txt ? JSON.parse(txt) : null; } catch (e) { data = { msg: txt }; } + + if (!res.ok) { + // 401/403 一律视为会话失效,回登录门 + if (res.status === 401 || res.status === 403) { + const e = new Error((data && data.msg) || '未授权'); + e.status = res.status; + throw e; + } + throw new Error((data && (data.msg || data.error)) || 'HTTP ' + res.status); + } + return data; +} + +// 订阅后端请求:URL 带 ?token=<订阅口令> +let RSS_TOKEN = localStorage.getItem(LS_RSS) || ''; + +async function rssApi(path, opt) { + opt = opt || {}; + const u = new URL(RSS_API + path); + if (RSS_TOKEN) u.searchParams.set('token', RSS_TOKEN); + + const headers = {}; + if (opt.body !== undefined) headers['Content-Type'] = 'application/json'; + + let res; + try { + res = await fetch(u.toString(), { + method: opt.method || 'GET', + headers, + body: opt.body !== undefined ? JSON.stringify(opt.body) : undefined, + signal: opt.signal, + }); + } catch (e) { + throw new Error('订阅后端网络不可达'); + } + + const txt = await res.text(); + let data = null; + try { data = txt ? JSON.parse(txt) : null; } catch (e) { data = { msg: txt }; } + + if (!res.ok) { + if (res.status === 401 || res.status === 403) { + const e = new Error((data && (data.error || data.msg)) || '订阅口令未授权'); + e.status = res.status; + throw e; + } + throw new Error((data && (data.error || data.msg)) || 'HTTP ' + res.status); + } + return data; +} + +// ============================================================ 提示 / 模态 + +let toastTimer = null; +function toast(msg, bad) { + const el = $('#toast'); + el.textContent = msg; + el.className = 'toast' + (bad ? ' bad' : ''); + el.hidden = false; + clearTimeout(toastTimer); + toastTimer = setTimeout(() => { el.hidden = true; }, 3200); +} + +function modal(title, html) { + $('#modalTitle').textContent = title; + $('#modalBody').innerHTML = html; + $('#modal').hidden = false; +} +function closeModal() { $('#modal').hidden = true; } + +function confirmBox(title, text, onYes) { + modal(title, + '

' + esc(text) + '

' + + '
' + + '' + + '' + + '
'); + $('#cfmYes').onclick = async () => { + const b = $('#cfmYes'); b.dataset.busy = '1'; + try { await onYes(); closeModal(); } + catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +// ============================================================ 登录 / 登出 + +function showGate() { + $('#app').hidden = true; + $('#gate').hidden = false; + setTimeout(() => { const i = $('#lgUser'); if (i) i.focus(); }, 60); +} + +function showApp() { + $('#gate').hidden = true; + $('#app').hidden = false; + $('#who').textContent = (state.me && (state.me.name || state.me.email)) || 'admin'; + $('#footR').textContent = 'API v2 · 站点:' + (state.site || '—'); + renderTabs(); + go('dash'); +} + +function logout(msg) { + TOKEN = ''; + state.me = null; + localStorage.removeItem(LS_T); + localStorage.removeItem(LS_U); + showGate(); + if (msg) { + const err = $('#lgErr'); + err.textContent = msg; + err.hidden = false; + } +} + +async function doLogin(email, password) { + const d = await api('/user/access_token', { method: 'POST', body: { email, password } }); + if (!d || !d.token) throw new Error('服务端未返回凭据'); + TOKEN = d.token; + state.me = d.user || null; + localStorage.setItem(LS_T, TOKEN); + try { localStorage.setItem(LS_U, JSON.stringify(state.me)); } catch (e) {} + return state.me; +} + +// ============================================================ 骨架 + +function renderTabs() { + // 分组渲染:group 为空的(仪表盘)单独在顶部;组间加分隔线 + let html = ''; + let lastGroup = null; + for (const t of TABS) { + if (t.group !== lastGroup) { + if (t.group) { + if (lastGroup !== null && lastGroup !== '') html += ''; + html += ''; + } else if (lastGroup !== null) { + html += ''; + } + lastGroup = t.group; + } + const badge = (t.id === 'comments' && state.pending > 0) + ? '' + state.pending + '' : ''; + html += ''; + } + $('#tabs').innerHTML = html; +} + +/** 更新顶栏面包屑:group / label */ +function renderCrumb() { + const t = TABS.find((x) => x.id === state.tab); + if (!t) return; + const el = $('#crumb'); + if (el) el.innerHTML = (t.group ? '' + esc(t.group) + '/' : '') + + '' + esc(t.label) + ''; +} + +function setBusy(sel, on) { + $$(sel).forEach((b) => { if (on) b.dataset.busy = '1'; else delete b.dataset.busy; }); +} + +// ============================================================ 路由 + +async function go(tab) { + state.tab = tab; + renderTabs(); + renderCrumb(); + closeSidebar(); // 移动端点完就收起抽屉 + const v = $('#view'); + v.innerHTML = '
加载中…
'; + try { + if (tab === 'dash') await viewDash(); + else if (tab === 'comments') await viewComments(); + else if (tab === 'pages') await viewPages(); + else if (tab === 'users') await viewUsers(); + else if (tab === 'settings') await viewSettings(); + else if (tab === 'status') await viewStatus(); + else if (tab === 'feeds') await viewFeeds(); + else if (tab === 'links') await viewLinks(); + else if (tab === 'images') await viewImages(); + } catch (e) { + if (e.status === 401 || e.status === 403) { logout('会话已失效,请重新登录'); return; } + if (state.tab !== tab) return; // 已切走,别用旧错误覆盖新视图 + v.innerHTML = '
出错了:' + esc(e.message) + '
'; + } +} + +// ============================================================ 视图:仪表盘 + +async function viewDash() { + const sn = state.site; + + const [total, pages, users, pend, latest, hot] = await Promise.all([ + api('/stats/site_comment?' + qs({ site_name: sn })), + api('/pages?' + qs({ site_name: sn, limit: 1 })), + api('/users/all?' + qs({ limit: 1 })), + api('/comments?' + qs({ scope: 'site', site_name: sn, type: 'pending', limit: 1 })), + api('/stats/latest_comments?' + qs({ limit: 8 })), + api('/stats/comment_most_pages?' + qs({ limit: 6 })), + ]); + + state.pending = pend.count || 0; + renderTabs(); + + const cards = [ + { k: '评论总数', v: total.data || 0, x: '站点「' + sn + '」' }, + { k: '涉及页面', v: pages.count || 0, x: '有评论记录的文章' }, + { k: '评论用户', v: users.count || 0, x: '去重后的人数' }, + { k: '待审核', v: state.pending, x: state.pending ? '需要处理' : '全部已处理' }, + ].map((c) => + '
' + c.k + '
' + + '
' + nfmt(c.v) + '
' + esc(c.x) + '
' + ).join(''); + + const latestRows = (latest.data || []).map((c) => + '
' + + '' + esc((c.date || '').slice(5, 16)) + '' + + '' + esc(c.nick) + ' ' + + '' + esc(truncate(String(c.content || '').replace(/<[^>]+>/g, ''), 44)) + '' + + '#' + c.id + '' + + '
' + ).join('') || '
暂无评论
'; + + const hotRows = (hot.data || []).map((p) => + '
' + + '' + esc(truncate(p.title || p.key, 26)) + ' ' + + '' + esc(p.key) + '' + + '' + nfmt(p.comment_count) + '' + + '
' + ).join('') || '
暂无数据
'; + + if (state.tab !== 'dash') return; + $('#view').innerHTML = + head('仪表盘', 'DASHBOARD', '站点 ' + sn + ' 的评论概览') + + '
' + cards + '
' + + '
' + + '

最新评论

' + + latestRows + '
' + + '

评论最多的文章

' + + hotRows + '
' + + '
'; +} + +function head(zh, en, sub, actions) { + void en; // 页头不再显示英文代号 + return '

' + esc(zh) + '

' + + (sub ? '' + esc(sub) + '' : '') + + (actions ? '
' + actions + '
' : '') + + '
'; +} + +// ============================================================ 视图:评论 + +async function viewComments() { + const c = state.c; + if (state.tab !== 'comments') return; + $('#view').innerHTML = + head('评论管理', 'COMMENTS', '', '') + + '
' + + '
' + + '' + + '' + + '
' + + '
加载中…
' + + '
'; + + const q = $('#cq'); + let tmr = null; + q.oninput = () => { + clearTimeout(tmr); + tmr = setTimeout(() => { c.q = q.value.trim(); c.offset = 0; loadComments(); }, 420); + }; + $('#ctype').onchange = (e) => { c.type = e.target.value; c.offset = 0; loadComments(); }; + $('#climit').onchange = (e) => { c.limit = parseInt(e.target.value, 10); c.offset = 0; loadComments(); }; + + await loadComments(); +} + +async function loadComments() { + const c = state.c; + const box = $('#clist'); + if (!box) return; + box.innerHTML = '
加载中…
'; + + // 待审视图走扁平模式:待审的可能是任意层级的回复,按“顶层分页”会整条漏掉 + const useFlat = c.type === 'pending'; + + const d = await api('/comments?' + qs({ + scope: 'site', + site_name: state.site, + type: useFlat ? 'pending' : '', + search: c.q, + limit: c.limit, + offset: c.offset, + flat_mode: useFlat ? 'true' : '', + })); + + if (state.tab !== 'comments' || !document.body.contains(box)) return; // 已切走,丢弃 + + // visible=false 是服务端为补全树而带出的“范围外父评论”,管理列表不需要 + c.rows = (d.comments || []).filter((x) => x.visible !== false); + c.total = d.count || 0; + // 树形视图按“顶层数”分页;扁平视图按总条数分页 + c.denom = useFlat ? c.total : (d.roots_count != null ? d.roots_count : c.total); + if (useFlat) state.pending = c.total; + renderTabs(); + + if (!c.rows.length) { + box.innerHTML = '
' + (c.q ? '没有匹配 “' + esc(c.q) + '” 的评论' : '暂无评论') + '
'; + $('#cpager').innerHTML = ''; + return; + } + + // 按父子关系组织 + const kids = new Map(); + const roots = []; + const ids = new Set(c.rows.map((x) => x.id)); + for (const r of c.rows) { + if (r.rid && ids.has(r.rid)) { + if (!kids.has(r.rid)) kids.set(r.rid, []); + kids.get(r.rid).push(r); + } else { + roots.push(r); + } + } + + box.innerHTML = '
' + roots.map((r) => node(r, kids, 0)).join('') + '
'; + + const pages = Math.max(1, Math.ceil(c.denom / c.limit)); + const cur = Math.floor(c.offset / c.limit) + 1; + $('#cpager').innerHTML = + '
' + + '' + + '第 ' + cur + ' / ' + pages + ' 页 · 共 ' + nfmt(c.total) + ' 条评论' + + (useFlat ? '(待审,按条)' : ' / ' + nfmt(c.denom) + ' 个主题') + '' + + '' + + '
'; +} + +function node(c, kids, depth) { + const cls = ['citem']; + if (c.is_pending) cls.push('pend'); + if (c.is_pinned) cls.push('pin'); + if (c.is_collapsed) cls.push('hid'); + if (depth > 0) cls.push('rep'); + + const tags = []; + if (c.is_pinned) tags.push('置顶'); + if (c.is_pending) tags.push('待审'); + if (c.is_collapsed) tags.push('折叠'); + if (c.badge_name) tags.push('' + esc(c.badge_name) + ''); + if (c.is_verified) tags.push('博主'); + + const ch = kids.get(c.id) || []; + const opened = state.openReps.has(c.id); + + // 头像:服务端给的 email_encrypted(md5),走前台同一套 weavatar 镜像 + const avatar = 'https://weavatar.com/avatar/' + esc(c.email_encrypted || '') + '?d=mp&s=80'; + + return '
' + + '
' + + '' + + '
' + + '
' + + '' + esc(c.nick) + '' + + tags.join('') + + '#' + c.id + ' · ' + esc(c.date) + '' + + '
' + + '
' + (plainify(c.content) || '(空内容)') + '
' + + '
' + + '' + + esc(truncate(c.page_key, 42)) + '' + + (ch.length ? ' · 回复 ' + ch.length + '' : '') + + (c.ua ? ' · ' + esc(truncate(c.ua.replace(/^Mozilla\/5\.0\s*/, ''), 26)) + '' : '') + + '' + + (ch.length ? '' : '') + + (c.is_pending ? '' : '') + + '' + + '' + + '' + + '' + + '
' + + (ch.length && opened ? '
' + ch.map((x) => node(x, kids, depth + 1)).join('') + '
' : '') + + '
' + + '
' + + '
'; +} + +// ============================================================ 视图:页面 + +async function viewPages() { + const p = state.p; + const d = await api('/pages?' + qs({ site_name: state.site, limit: p.limit, offset: p.offset })); + p.total = d.count || 0; + const rows = d.pages || []; + + if (state.tab !== 'pages') return; + $('#view').innerHTML = + head('页面', 'PAGES', '共 ' + nfmt(p.total) + ' 个有评论记录的页面') + + (rows.length + ? '
' + + '' + + '' + + rows.map((r) => + '' + + '' + + '' + + '' + + '' + + '').join('') + + '
页面标题访问路径票数最近活动
' + (esc(r.title) || '(无标题)') + '' + esc(r.key) + '' + nfmt(r.vote_up) + ' / ' + nfmt(r.vote_down) + '' + esc(r.date) + '
' + + pager('p', p, '页') + : '
暂无页面
'); +} + +function pager(prefix, st, unit) { + const pages = Math.max(1, Math.ceil(st.total / st.limit)); + const cur = Math.floor(st.offset / st.limit) + 1; + return '
' + + '' + + '第 ' + cur + ' / ' + pages + ' 页 · 共 ' + nfmt(st.total) + ' ' + unit + '' + + '' + + '
'; +} + +// ============================================================ 视图:用户 + +async function viewUsers() { + const u = state.u; + if (state.tab !== 'users') return; + $('#view').innerHTML = + head('用户', 'USERS', '', '') + + '
' + + '
加载中…
'; + + const q = $('#uq'); + let tmr = null; + q.oninput = () => { + clearTimeout(tmr); + tmr = setTimeout(() => { u.q = q.value.trim(); u.offset = 0; loadUsers(); }, 420); + }; + await loadUsers(); +} + +async function loadUsers() { + const u = state.u; + const box = $('#ulist'); + if (!box) return; + box.innerHTML = '
加载中…
'; + + const d = await api('/users/all?' + qs({ + limit: u.limit, offset: u.offset, + name: u.q.indexOf('@') < 0 ? u.q : '', + email: u.q.indexOf('@') >= 0 ? u.q : '', + })); + u.total = d.count || 0; + + if (state.tab !== 'users' || !document.body.contains(box)) return; // 已切走,丢弃 + + const rows = d.users || []; + u.rows = rows; // 供编辑弹窗取行数据(API 单页上限 200,不能靠再查一次兜住 492 个用户) + const html = rows.length + ? '
' + + '' + + '' + + rows.map((r) => + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '').join('') + + '
昵称邮箱评论徽章近期 IP
' + esc(r.name) + '' + (r.is_admin ? ' 管理员' : '') + '' + esc(r.email) + '' + nfmt(r.comment_count) + '' + (r.badge_name + ? '' + esc(r.badge_name) + '' + : '—') + '' + esc(r.last_ip || '—') + '
' + pager('u', u, '个用户') + : '
没有匹配的用户
'; + + box.innerHTML = html; +} + +function editUser(id) { + (function () { + const u = (state.u.rows || []).filter((x) => x.id === id)[0]; + if (!u) { toast('用户不存在,请刷新列表', true); return; } + modal('编辑用户 #' + id, + '' + + '' + + '' + + '
' + + '' + + '' + + '
' + + '' + + '' + + '' + + ''); + + $('#euSave').onclick = async () => { + const body = { + name: $('#euName').value.trim(), + email: $('#euMail').value.trim(), + link: $('#euLink').value.trim(), + badge_name: $('#euBn').value.trim(), + badge_color: $('#euBc').value.trim(), + title_name: $('#euTitle').value.trim(), + is_admin: $('#euAdm').checked, + }; + const pw = $('#euPw').value; + if (pw) body.password = pw; + const b = $('#euSave'); b.dataset.busy = '1'; + try { + await api('/users/' + id, { method: 'PUT', body: body }); + closeModal(); toast('✓ 已保存'); + loadUsers(); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; + })(); +} + +// ============================================================ 视图:设置 + +async function viewSettings() { + const [sites, conf] = await Promise.all([api('/sites'), api('/conf')]); + state.sites = sites || []; + const fe = conf.frontend_conf || {}; + + if (state.tab !== 'settings') return; + const siteRows = state.sites.map((s) => + '
' + + '' + esc(s.name) + ' ' + + '' + esc((s.urls || []).join(', ')) + '' + + '' + + '
').join('') || '
暂无站点
'; + + const feRows = [ + ['评论分页', (fe.pagination && fe.pagination.pageSize) || 20, '条/页'], + ['初始加载', fe.countOfCommentsOnPageInit || 20, '条'], + ['验证码', fe.captchaMode || 'off', ''], + ['投票', fe.vote ? '开启' : '关闭', ''], + ['图片上传', fe.imgUpload ? '可用' : '不可用', ''], + ['语言', fe.locale || 'zh-CN', ''], + ['表情包', fe.emoticons || '—', ''], + ['头像源', (fe.gravatar && fe.gravatar.mirror) || '', ''], + ].map((r) => + '
' + esc(r[0]) + '
' + esc(String(r[1])) + (r[2] ? ' ' + esc(r[2]) + '' : '') + '
' + ).join(''); + + $('#view').innerHTML = + head('设置', 'SETTINGS', '站点与前台配置') + + '
' + + '

站点

' + siteRows + '
' + + '

前台配置

' + feRows + '
' + + '
' + + '

服务端配置

' + + '
加载中…
'; + + api('/settings').then((d) => { + const box = $('#yamlBox'); + if (!box) return; + box.innerHTML = + '' + + '
' + + '' + + '' + + '' + + '
' + + '

' + + '保存在 D1 settings 表,改完即刻生效。服务端识别的键:' + + 'frontend.*(前台配置,含 emoticons 表情包地址)、' + + 'captcha 验证码、moderator.pending_default 待审、' + + 'ip_region 归属地、site_default 默认站点名;其余键仅存档。

'; + + let original = d.yaml || ''; + + // IP 归属地快捷开关:读写 yaml 里的 ip_region.enabled(与 sidebar 设置页同一份数据) + var ipOn = /ip_region:[\s\S]*?enabled:\s*true/.test(original); + var ipRow = document.createElement('div'); + ipRow.style.cssText = 'display:flex;align-items:center;gap:8px;margin-bottom:10px;padding:10px 12px;' + + 'background:var(--surface);border:1px solid var(--line);border-radius:6px'; + ipRow.innerHTML = + '' + + '' + + '(同 sidebar 设置页的 ip_region.enabled)'; + var txt = $('#yamlTxt'); + txt.parentNode.insertBefore(ipRow, txt); + ipRow.querySelector('#ipRegionToggle').addEventListener('change', function () { + var on = this.checked; + var t = $('#yamlTxt'); + var v = t.value; + if (/ip_region:[\s\S]*?enabled:\s*(true|false)/.test(v)) { + v = v.replace(/(ip_region:[\s\S]*?enabled:\s*)(true|false)/, '$1' + on); + } else { + v += (v.endsWith('\n') ? '' : '\n') + 'ip_region://n enabled: ' + on + '\n'; + } + t.value = v; + toast('已切换为 ' + (on ? '显示' : '隐藏') + ',保存后生效'); + }); + + // 人机验证快捷开关(自研「一键验证」):读写 yaml 里的 human_check.enabled, + // 保存时由服务端同步到 KV(评论提交时读 KV,不占 D1 额度) + var hcOn = /human_check:[\s\S]*?enabled://s*true/.test(original); + var hcRow = document.createElement('div'); + hcRow.style.cssText = 'display:flex;align-items:center;gap:8px;margin-bottom:10px;padding:10px 12px;' + + 'background:var(--surface);border:1px solid var(--line);border-radius:6px'; + hcRow.innerHTML = + '' + + '' + + '(human_check.enabled)'; + ipRow.parentNode.insertBefore(hcRow, ipRow.nextSibling); + hcRow.querySelector('#humanCheckToggle').addEventListener('change', function () { + var on = this.checked; + var t = $('#yamlTxt'); + var v = t.value; + if (/human_check:[\s\S]*?enabled://s*(true|false)/.test(v)) { + v = v.replace(/(human_check:[\s\S]*?enabled://s*)(true|false)/, '$1' + on); + } else { + v += (v.endsWith('\n') ? '' : '\n') + 'human_check://n enabled: ' + on + '\n'; + } + t.value = v; + toast('人机验证已' + (on ? '开启' : '关闭') + ',保存后生效'); + }); + + const $r = () => $('#yamlReset'); + if ($r()) $r().onclick = () => { $('#yamlTxt').value = original; toast('已还原'); }; + + const $s = () => $('#yamlSave'); + if ($s()) $s().onclick = async () => { + const b = $s(); b.dataset.busy = '1'; + const msg = $('#yamlMsg'); if (msg) msg.textContent = '保存中…'; + try { + const r = await api('/settings', { method: 'PUT', body: { yaml: $('#yamlTxt').value } }); + original = $('#yamlTxt').value; + if (msg) msg.textContent = ''; + toast('✓ 已保存' + (r && r.msg ? '' : '')); + viewSettings(); // 重新拉取,让上方"前台配置"卡片同步刷新 + } catch (e) { + if (msg) msg.textContent = ''; + toast('✕ ' + e.message, true); + delete b.dataset.busy; + } + }; + }).catch(() => { const b = $('#yamlBox'); if (b) b.innerHTML = '
读取失败
'; }); +} + +function editSite(id) { + const s = state.sites.filter((x) => x.id === id)[0]; + if (!s) return; + modal('编辑站点 #' + id, + '' + + '' + + '

改站点名会让前台 site 与数据对不上,除非你同步改博客配置。

' + + ''); + + $('#esSave').onclick = async () => { + const b = $('#esSave'); b.dataset.busy = '1'; + try { + await api('/sites/' + id, { + method: 'PUT', + body: { name: $('#esName').value.trim(), urls: $('#esUrls').value.split('\n').map((x) => x.trim()).filter(Boolean).join(',') }, + }); + closeModal(); toast('✓ 已保存'); + go('settings'); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +// ============================================================ 视图:状态 + +async function viewStatus() { + const h = await api('/healthz'); + let v = {}; + try { v = await api('/version'); } catch (e) {} + + const okDd = (x) => '
' + (x ? 'OK' : 'FAIL') + '
'; + + if (state.tab !== 'status') return; + $('#view').innerHTML = + head('系统状态', 'STATUS', '运行时自检') + + '
' + + '

服务端自检

' + + '
D1 数据库
' + okDd(h.db === 'up') + + '
评论总数
' + nfmt(h.comments) + '
' + + '
查询延迟
' + esc(h.latency_ms) + ' ms
' + + '
API 版本
' + esc(h.version) + '
' + + '
' + + '

运行时

' + + '
应用
' + esc(v.app || 'artalk') + '
' + + '
版本
' + esc(v.version || '—') + '
' + + '
提交
' + esc(v.commit_hash || '—') + '
' + + '
端点
' + esc(location.origin) + '
' + + '
登录身份
' + esc((state.me && (state.me.name || state.me.email)) || '—') + '
' + + '
' + + '
' + + '

注意事项

' + + '
' + + '
邮件通知
' + + (h.mail === 'on' ? '已启用(Resend)' : '未配置 —— 需写入 RESEND_API_KEY') + '
' + + '
验证码登录
不可用 —— Workers 无 TCP,发不了 SMTP
' + + '
官方后台
可用 —— ' + esc(location.origin) + '/sidebar/
' + + '
慢查询
跨境访问有 RTT 开销,评论列表为动态接口无法走 CDN 缓存
' + + '
'; +} + +// ============================================================ 视图:订阅源 +// 数据来自 rss-robot-cf(api.200181.xyz) + +async function viewFeeds() { + if (state.tab !== 'feeds') return; + $('#view').innerHTML = + head('订阅源管理', 'FEEDS', 'RSS 订阅源 · ' + RSS_API, ''); + + let data; + try { + data = await rssApi('/api/feeds'); + } catch (e) { + if (e.status === 401 || e.status === 403) { + $('#view').innerHTML = head('订阅源管理', 'FEEDS', '需要订阅口令') + + '
未配置订阅口令 —— 请退出后重新登录,并在登录页填写「订阅口令」。
'; + return; + } + $('#view').innerHTML += '
加载失败:' + esc(e.message) + '
'; + return; + } + + const feeds = data.feeds || []; + state.feedsRows = feeds; // 编辑弹窗取数用 + const rows = feeds.map((f) => + '
' + + '' + esc(f.feedTitle || f.url) + ' ' + + '' + esc(f.url) + '' + + '' + + '' + + '' + + '' + + '
').join('') || '
暂无订阅源
'; + + $('#view').innerHTML += + '

订阅源(' + feeds.length + ')

' + + '
' + + '
' + rows + '
'; +} + +function addFeed() { + modal('添加订阅源', + '' + + '' + + ''); + $('#fSave').onclick = async () => { + const b = $('#fSave'); b.dataset.busy = '1'; + try { + await rssApi('/api/feeds', { method: 'POST', body: { url: $('#fUrl').value.trim(), feedTitle: $('#fTitle').value.trim() } }); + closeModal(); toast('✓ 已添加'); viewFeeds(); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +function editFeed(url) { + const f = (state.feedsRows || []).filter((x) => x.url === url)[0]; + if (!f) { toast('订阅源不存在,请刷新', true); return; } + modal('编辑订阅源', + '' + + '' + + '

改地址不会丢抓取记录 —— 服务端按原地址定位后更新。

' + + ''); + $('#feSave').onclick = async () => { + const b = $('#feSave'); b.dataset.busy = '1'; + try { + await rssApi('/api/feeds', { + method: 'POST', + body: { url: $('#feUrl').value.trim(), feedTitle: $('#feTitle').value.trim(), oldUrl: f.url }, + }); + closeModal(); toast('✓ 已保存'); viewFeeds(); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +// ============================================================ 视图:友链 + +async function viewLinks() { + if (state.tab !== 'links') return; + $('#view').innerHTML = + head('友链管理', 'LINKS', '友链 · ' + RSS_API, ''); + + let data; + let apps = []; + try { + data = await rssApi('/api/links?all=1'); + try { + const ad = await rssApi('/api/link-apply/list'); + apps = (ad.apps || []).filter((a) => a.status === 'pending'); + } catch (e) { /* 申请列表加载失败不阻塞友链展示 */ } + } catch (e) { + if (e.status === 401 || e.status === 403) { + $('#view').innerHTML = head('友链管理', 'LINKS', '需要订阅口令') + + '
未配置订阅口令 —— 请退出后重新登录。
'; + return; + } + $('#view').innerHTML += '
加载失败:' + esc(e.message) + '
'; + return; + } + + state.linkApps = apps; + + // 待审申请卡片 + let appHtml = ''; + if (apps.length) { + const appRows = apps.map((a) => + '
' + + '' + esc(a.name) + ' ' + + '' + esc(a.url) + (a.feed ? ' · RSS' : '') + (a.email ? ' · ' + esc(a.email) : '') + '' + + (a.description ? '' + esc(a.description) + '' : '') + + '' + + '' + + '' + + '' + + '' + + '' + + '
').join(''); + appHtml = + '

待审申请(' + apps.length + ')

' + + '新
' + + '
' + appRows + '
'; + } + + const links = data.links || []; + state.linksRows = links; + const rows = links.map((l) => + '
' + + '' + esc(l.name || l.url) + (l.hidden ? ' 隐藏' : '') + ' ' + + '' + esc(l.url) + (l.rss ? ' · RSS' : '') + '' + + '' + + '' + + '' + + '' + + '
').join('') || '
暂无友链
'; + + $('#view').innerHTML += appHtml + + '

友链(' + links.length + ')

' + + '
' + + '
' + rows + '
'; +} + +function viewLinkApply(id) { + const a = (state.linkApps || []).find((x) => x.id === id); + if (!a) return toast('✕ 申请不存在', true); + modal('友链申请 · ' + a.name, + '
' + + '
名称:' + esc(a.name) + '
' + + '' + + '
订阅:' + esc(a.feed || '—') + '
' + + '
邮箱:' + esc(a.email) + '
' + + (a.description ? '
描述:' + esc(a.description) + '
' : '') + + '
申请时间:' + esc(a.appliedAt) + '
' + + '
' + + '' + + '
' + + '' + + '' + + '
'); + $('#laApprove').onclick = async () => { + try { + await rssApi('/api/link-apply/review', { method: 'POST', body: { id, action: 'approve', feedback: $('#laFeedback').value.trim() } }); + closeModal(); toast('✓ 已通过并邮件通知申请人'); viewLinks(); + } catch (e) { toast('✕ ' + e.message, true); } + }; + $('#laReject').onclick = async () => { + try { + await rssApi('/api/link-apply/review', { method: 'POST', body: { id, action: 'reject', feedback: $('#laFeedback').value.trim() } }); + closeModal(); toast('✓ 已拒绝并邮件告知申请人'); viewLinks(); + } catch (e) { toast('✕ ' + e.message, true); } + }; +} + +function addLink() { + modal('添加友链', + '' + + '' + + '' + + ''); + $('#lSave').onclick = async () => { + const b = $('#lSave'); b.dataset.busy = '1'; + try { + await rssApi('/api/links', { method: 'POST', body: { name: $('#lName').value.trim(), url: $('#lUrl').value.trim(), description: $('#lDesc').value.trim() } }); + closeModal(); toast('✓ 已添加'); viewLinks(); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +function editLink(url) { + const l = (state.linksRows || []).filter((x) => x.url === url)[0]; + if (!l) { toast('友链不存在,请刷新', true); return; } + modal('编辑友链', + '' + + '' + + '' + + '' + + '' + + ''); + $('#leSave').onclick = async () => { + const b = $('#leSave'); b.dataset.busy = '1'; + try { + await rssApi('/api/links', { + method: 'POST', + body: { + name: $('#leName').value.trim(), + url: $('#leUrl').value.trim(), + description: $('#leDesc').value.trim(), + rss: $('#leRss').value.trim(), + hidden: $('#leHidden').checked, + oldUrl: l.url, + }, + }); + closeModal(); toast('✓ 已保存'); viewLinks(); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +// ============================================================ 视图:图片 + +async function viewImages() { + if (state.tab !== 'images') return; + $('#view').innerHTML = + head('图片管理', 'IMAGES', '随机图 · ' + RSS_API, ''); + + let folders; + try { + const d = await rssApi('/api/random-image?list=1'); + folders = d.folders || []; + } catch (e) { + $('#view').innerHTML += '
加载失败:' + esc(e.message) + '
'; + return; + } + + const rows = folders.map((f) => + '
' + esc(f) + '' + + '查看
' + ).join('') || '
暂无图片文件夹
'; + + $('#view').innerHTML += + '

图片文件夹(' + folders.length + ')

' + + '
' + + '
' + rows + '
'; +} + +function addImage() { + modal('添加图片', + '' + + '' + + ''); + $('#iSave').onclick = async () => { + const b = $('#iSave'); b.dataset.busy = '1'; + try { + const urls = $('#iUrls').value.split('\n').map((s) => s.trim()).filter(Boolean); + const folder = $('#iFolder').value.trim() || 'jiege'; + await rssApi('/api/random-image?folder=' + encodeURIComponent(folder), { method: 'POST', body: { urls } }); + closeModal(); toast('✓ 已添加'); viewImages(); + } catch (e) { toast('✕ ' + e.message, true); delete b.dataset.busy; } + }; +} + +// ============================================================ 侧边栏抽屉 / 主题 + +function closeSidebar() { + const sb = $('#sidebar'), sc = $('#scrim'); + if (sb) sb.classList.remove('open'); + if (sc) sc.hidden = true; +} + +function toggleSidebar() { + const sb = $('#sidebar'), sc = $('#scrim'); + if (!sb) return; + const open = sb.classList.toggle('open'); + if (sc) sc.hidden = !open; +} + +function applyTheme(t) { + if (t === 'dark') document.documentElement.dataset.theme = 'dark'; + else delete document.documentElement.dataset.theme; + const b = $('#themeBtn'); + if (b) b.innerHTML = ICONS.moon + '' + (t === 'dark' ? '浅色模式' : '深色模式') + ''; +} + +function toggleTheme() { + const cur = document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light'; + const next = cur === 'dark' ? 'light' : 'dark'; + try { localStorage.setItem('atk-theme', next); } catch (e) {} + applyTheme(next); +} + +// ============================================================ 事件委托 + +document.addEventListener('click', async (e) => { + const el = e.target.closest('[data-act]'); + if (!el) return; + const act = el.dataset.act; + const id = el.dataset.id ? parseInt(el.dataset.id, 10) : 0; + + // --- 通用 + if (act === 'modal-close') { closeModal(); return; } + if (act === 'menu') { toggleSidebar(); return; } + if (act === 'theme') { toggleTheme(); return; } + if (act === 'tab') { if (state.tab !== el.dataset.id) go(el.dataset.id); return; } + if (act === 'logout') { + confirmBox('退出登录', '确定要退出当前会话吗?', () => logout()); + return; + } + + // --- 评论 + if (act === 'c-reload') { el.dataset.busy = '1'; try { await loadComments(); } finally { delete el.dataset.busy; } return; } + if (act === 'c-prev') { state.c.offset = Math.max(0, state.c.offset - state.c.limit); await loadComments(); return; } + if (act === 'c-next') { state.c.offset += state.c.limit; await loadComments(); return; } + if (act === 'c-toggle') { + if (state.openReps.has(id)) state.openReps.delete(id); else state.openReps.add(id); + await loadComments(); + return; + } + if (act === 'c-approve' || act === 'c-pin' || act === 'c-fold') { + const body = {}; + if (act === 'c-approve') body.is_pending = false; + if (act === 'c-pin') body.is_pinned = el.dataset.v === '1'; + if (act === 'c-fold') body.is_collapsed = el.dataset.v === '1'; + el.dataset.busy = '1'; + try { + await api('/comments/' + id, { method: 'PUT', body: body }); + toast('✓ 已更新 #' + id); + await loadComments(); + } catch (ex) { toast('✕ ' + ex.message, true); delete el.dataset.busy; } + return; + } + if (act === 'c-del') { + confirmBox('删除评论 #' + id, '删除后前台不再显示(软删除,数据仍在库里)。确定继续?', async () => { + await api('/comments/' + id, { method: 'DELETE' }); + toast('✓ 已删除 #' + id); + await loadComments(); + }); + return; + } + + // --- 页面 + if (act === 'p-prev') { state.p.offset = Math.max(0, state.p.offset - state.p.limit); go('pages'); return; } + if (act === 'p-next') { state.p.offset += state.p.limit; go('pages'); return; } + + // --- 用户 + if (act === 'u-reload') { el.dataset.busy = '1'; try { await loadUsers(); } finally { delete el.dataset.busy; } return; } + if (act === 'u-prev') { state.u.offset = Math.max(0, state.u.offset - state.u.limit); await loadUsers(); return; } + if (act === 'u-next') { state.u.offset += state.u.limit; await loadUsers(); return; } + if (act === 'u-edit') { editUser(id); return; } + + // --- 站点 + if (act === 's-edit') { editSite(id); return; } + + // --- 订阅源 + if (act === 'f-reload') { el.dataset.busy = '1'; try { await viewFeeds(); } finally { delete el.dataset.busy; } return; } + if (act === 'f-add') { addFeed(); return; } + if (act === 'f-edit') { editFeed(el.dataset.url); return; } + if (act === 'f-del') { + const u = el.dataset.url; + confirmBox('删除订阅源', '确定删除「' + (u || '') + '」吗?', async () => { + await rssApi('/api/feeds?url=' + encodeURIComponent(u), { method: 'DELETE' }); + toast('✓ 已删除'); + await viewFeeds(); + }); + return; + } + + // --- 友链申请审核 + if (act === 'l-ap-view' || act === 'l-ap-reject') { viewLinkApply(id); return; } + if (act === 'l-ap-approve') { + const a = (state.linkApps || []).find((x) => x.id === id); + confirmBox('通过申请', '确定通过「' + (a ? a.name : '') + '」的友链申请吗?通过后自动加进友链并邮件通知对方。', async () => { + await rssApi('/api/link-apply/review', { method: 'POST', body: { id, action: 'approve' } }); + toast('✓ 已通过'); await viewLinks(); + }); + return; + } + // --- 友链 + if (act === 'l-reload') { el.dataset.busy = '1'; try { await viewLinks(); } finally { delete el.dataset.busy; } return; } + if (act === 'l-add') { addLink(); return; } + if (act === 'l-edit') { editLink(el.dataset.url); return; } + if (act === 'l-del') { + const u = el.dataset.url; + confirmBox('删除友链', '确定删除「' + (u || '') + '」吗?', async () => { + await rssApi('/api/links?url=' + encodeURIComponent(u), { method: 'DELETE' }); + toast('✓ 已删除'); + await viewLinks(); + }); + return; + } + + // --- 图片 + if (act === 'i-reload') { el.dataset.busy = '1'; try { await viewImages(); } finally { delete el.dataset.busy; } return; } + if (act === 'i-add') { addImage(); return; } +}); + +// ============================================================ 启动 + +$('#loginForm').addEventListener('submit', async (e) => { + e.preventDefault(); + const btn = $('#lgBtn'); + const err = $('#lgErr'); + err.hidden = true; + btn.dataset.busy = '1'; + try { + await doLogin($('#lgUser').value.trim(), $('#lgPass').value); + state.me = state.me || {}; + if (state.me.is_admin === false) throw new Error('该账号不是管理员'); + + // 订阅口令:填了就验证并存下,没填就清空(订阅模块会提示未配置) + const rssPwd = $('#lgRss') ? $('#lgRss').value.trim() : ''; + if (rssPwd) { + const ok = await rssApi('/api/auth?token=' + encodeURIComponent(rssPwd)); + if (!ok || ok.ok !== true) throw new Error('订阅口令错误'); + RSS_TOKEN = rssPwd; + localStorage.setItem(LS_RSS, rssPwd); + } else { + RSS_TOKEN = localStorage.getItem(LS_RSS) || ''; + } + + await bootstrap(); + } catch (ex) { + err.textContent = '✕ ' + ex.message; + err.hidden = false; + TOKEN = ''; + localStorage.removeItem(LS_T); + } finally { + delete btn.dataset.busy; + } +}); + +async function bootstrap() { + // 站点列表 -> 默认站点 + const sites = await api('/sites'); + state.sites = sites || []; + let def = state.sites[0] ? state.sites[0].name : ''; + try { + const c = await api('/conf'); + if (c && c.frontend_conf && c.frontend_conf.site_default) def = c.frontend_conf.site_default; + } catch (e) {} + if (!def && state.sites[0]) def = state.sites[0].name; + state.site = def; + + // 待审数量(供导航徽章) + try { + const p = await api('/comments?' + qs({ scope: 'site', site_name: state.site, type: 'pending', limit: 1 })); + state.pending = p.count || 0; + } catch (e) {} + + showApp(); +} + +applyTheme(document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light'); + +(async function boot() { + if (!TOKEN) { showGate(); return; } + try { + // /user 未登录时返回 200 + {user:null},所以要显式判 is_login + const me = await api('/user'); + if (!me || !me.user || !me.is_login) throw Object.assign(new Error('会话已失效'), { status: 401 }); + state.me = me.user; + if (state.me.is_admin === false) throw Object.assign(new Error('该账号不是管理员'), { status: 403 }); + localStorage.setItem(LS_U, JSON.stringify(state.me)); + await bootstrap(); + } catch (e) { + logout(e.status ? '会话已失效,请重新登录' : ('连接失败:' + e.message)); + } +})(); + +})(); \ No newline at end of file diff --git a/blog-admin/public/admin/index.html b/blog-admin/public/admin/index.html new file mode 100644 index 00000000..7fcbad9e --- /dev/null +++ b/blog-admin/public/admin/index.html @@ -0,0 +1,98 @@ + + + + + +管理面板 · 优世界 + + + + + + + + + + + + + + + + + + + diff --git a/blog-admin/public/dist/Artalk.css b/blog-admin/public/dist/Artalk.css new file mode 100644 index 00000000..dbfea520 --- /dev/null +++ b/blog-admin/public/dist/Artalk.css @@ -0,0 +1 @@ +@charset "UTF-8";.artalk,.atk-layer-wrap{--at-color-font: #2a2e2e;--at-color-deep: #2a2e2e;--at-color-sub: #757575;--at-color-grey: #747474;--at-color-meta: #697182;--at-color-border: #eceff2;--at-color-light: #4285f4;--at-color-bg: #fff;--at-color-bg-transl: rgba(255, 255, 255, .94);--at-color-bg-grey: #f3f4f5;--at-color-bg-grey-transl: rgba(244, 244, 244, .75);--at-color-bg-light: rgba(29, 161, 242, .1);--at-color-main: #0083ff;--at-color-red: #ff5652;--at-color-pink: #fa5a57;--at-color-yellow: #ff7c37;--at-color-green: #4caf50;--at-color-gradient: linear-gradient(180deg, transparent, rgba(255, 255, 255))}.artalk.atk-dark-mode,.atk-layer-wrap.atk-dark-mode{--at-color-font: #fff;--at-color-deep: #e7e7e7;--at-color-sub: #e7e7e7;--at-color-grey: #fff;--at-color-meta: #fff;--at-color-border: #2d3235;--at-color-light: #687a86;--at-color-bg: #1e2224;--at-color-bg-transl: rgba(30, 34, 36, .95);--at-color-bg-grey: #46494e;--at-color-bg-grey-transl: rgba(8, 8, 8, .95);--at-color-bg-light: rgba(29, 161, 242, .1);--at-color-main: #0083ff;--at-color-red: #ff5652;--at-color-pink: #fa5a57;--at-color-yellow: #ff7c37;--at-color-green: #4caf50;--at-color-gradient: linear-gradient(180deg, transparent, rgba(30, 34, 36, 1))}.atk-comment-wrap{overflow:hidden;position:relative;border-bottom:1px solid transparent}.atk-comment-wrap.atk-flash-once{animation:atkFlashOnce 1s ease-in-out 0s}@keyframes atkFlashOnce{0%{background:#0083ff33}to{background:transparent}}.atk-comment-wrap.atk-unread:before{content:" ";position:absolute;left:0;top:10%;width:3px;height:80%;background:var(--at-color-main)}.atk-comment-wrap.atk-openable{cursor:pointer}.atk-comment-wrap.atk-openable:hover{background:var(--at-color-bg-grey)}.atk-comment-wrap.atk-openable .atk-height-limit:after{background:transparent!important}.atk-comment-wrap:last-child{border-bottom:none}.atk-comment{display:block;padding:10px}.atk-comment>.atk-avatar{display:block;padding:2px 0;float:left}.atk-comment>.atk-avatar img{width:50px;height:50px;border-radius:3px}.atk-comment>.atk-main{display:block;margin-left:63px}.atk-comment>.atk-main>.atk-header{line-height:1.5;font-size:13px;margin-bottom:.5em;overflow:hidden;position:relative;display:flex;flex-wrap:wrap;align-items:center}.atk-comment>.atk-main>.atk-header .atk-item{display:flex;align-items:center;margin-top:2px;margin-bottom:2px;color:var(--at-color-meta)}.atk-comment>.atk-main>.atk-header .atk-item:not(:last-child){margin-right:6px}.atk-comment>.atk-main>.atk-header .atk-item.atk-nick,.atk-comment>.atk-main>.atk-header .atk-item.atk-nick a{font-size:14px;color:var(--at-color-main);text-decoration:none}.atk-comment>.atk-main>.atk-header .atk-item.atk-reply-at{margin-left:2px}.atk-comment>.atk-main>.atk-header .atk-item.atk-reply-at>.atk-arrow:before{content:"";vertical-align:middle;transform:rotate(90deg);border-bottom:4px solid var(--at-color-grey);border-left:3px solid transparent;border-right:3px solid transparent;display:inline-block;margin-top:-1px}.atk-comment>.atk-main>.atk-header .atk-item.atk-reply-at>.atk-nick{color:var(--at-color-main);cursor:pointer;margin-left:6px}.atk-comment>.atk-main>.atk-header .badge,.atk-comment>.atk-main>.atk-header .atk-ua,.atk-comment>.atk-main>.atk-header .atk-pinned-badge,.atk-comment>.atk-main>.atk-header .atk-region-badge,.atk-comment>.atk-main>.atk-header .atk-badge{display:inline-block;color:var(--at-color-meta);background:var(--at-color-bg-grey);padding:0 6px;line-height:17px;border-radius:3px}.atk-comment>.atk-main>.atk-header .badge:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-ua:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-pinned-badge:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-region-badge:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-badge:not(:last-child){margin-right:6px}.atk-comment>.atk-main>.atk-header .atk-badge-wrap>*:last-child{margin-right:6px}.atk-comment>.atk-main>.atk-header .atk-badge{color:#fff}.atk-comment>.atk-main>.atk-header .atk-pinned-badge{color:#fff;background:#f44336}.atk-comment>.atk-main>.atk-header .atk-verified-icon{height:1.4em;width:1.4em;background-repeat:no-repeat;background-position:center;background-size:contain;display:block;background-image:url('data:image/svg+xml,')}@media only screen and (max-width: 768px){.atk-comment>.atk-main>.atk-header .atk-ua-wrap{display:block}}.atk-comment>.atk-main>.atk-body{display:block;overflow:hidden;position:relative}.atk-comment>.atk-main>.atk-body img{max-width:100%}.atk-comment>.atk-main>.atk-body>.atk-content{word-break:break-word}.atk-comment>.atk-main>.atk-body>.atk-content.atk-type-collapsed{border:3px solid var(--at-color-bg-grey);border-bottom:0;padding:5px 10px;border-radius:6px 6px 0 0;margin-bottom:-5px}.atk-comment>.atk-main>.atk-body>.atk-content>*:first-child{margin-top:0}.atk-comment>.atk-main>.atk-body>.atk-content>*:last-child{margin-bottom:0}.atk-comment>.atk-main>.atk-body>.atk-content .atk-height-limit-btn{bottom:5px}.atk-comment>.atk-main>.atk-body>.atk-pending{color:var(--at-color-meta);margin:3px 0;font-size:13px;padding:10px 18px;display:block;background:var(--at-color-bg-grey);border-left:4px solid #f44336}.atk-comment>.atk-main>.atk-body>.atk-reply-to{padding:5px 15px;border-left:3px solid var(--at-color-border);margin-bottom:10px;position:relative;margin-top:10px}.atk-comment>.atk-main>.atk-body>.atk-reply-to .atk-meta{font-size:15px}.atk-comment>.atk-main>.atk-body>.atk-reply-to .atk-meta .atk-nick{color:var(--at-color-main)}.atk-comment>.atk-main>.atk-body>.atk-reply-to .atk-content{margin-top:5px}.atk-comment>.atk-main>.atk-body>.atk-collapsed{margin:3px 0;font-size:13px;padding:10px 18px;display:block;background:var(--at-color-bg-grey);border-radius:6px}.atk-comment>.atk-main>.atk-body>.atk-collapsed .atk-text{color:var(--at-color-meta)}.atk-comment>.atk-main>.atk-body>.atk-collapsed .atk-show-btn{color:var(--at-color-main);cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-left:3px}.atk-comment>.atk-main>.atk-body>.atk-collapsed .atk-show-btn:hover{color:var(--at-color-main)}.atk-comment>.atk-main>.atk-footer{margin-top:5px}.atk-comment>.atk-main>.atk-footer .atk-actions{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.atk-comment>.atk-main>.atk-footer .atk-actions>span{color:var(--at-color-meta);font-size:13px;line-height:25px;display:inline-flex;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.atk-comment>.atk-main>.atk-footer .atk-actions>span.atk-error,.atk-comment>.atk-main>.atk-footer .atk-actions>span.atk-error:hover{color:var(--at-color-red)}.atk-comment>.atk-main>.atk-footer .atk-actions>span:not(:last-child):not(.atk-hide){margin-right:16px}.atk-comment>.atk-main>.atk-footer .atk-actions>span:hover{color:var(--at-color-deep)}.atk-comment .atk-height-limit:after{position:absolute;z-index:1;display:block;overflow:hidden;width:100%;content:" ";bottom:0;height:80px;background:var(--at-color-gradient)}.atk-comment .atk-height-limit-btn{z-index:2;position:absolute;left:50%;bottom:10px;transform:translate(-50%);cursor:pointer;border:1px solid var(--at-color-border);border-radius:6px;background:var(--at-color-bg);padding:1px 20px;font-size:15px;color:var(--at-color-meta);-webkit-user-select:none;-moz-user-select:none;user-select:none}.atk-comment .atk-height-limit-btn:hover{background:var(--at-color-bg-grey)}.atk-comment .atk-height-limit .atk-height-limit .atk-height-limit-btn{display:none}.atk-comment .atk-height-limit-scroll{margin-top:10px;overflow-y:auto;background:linear-gradient(var(--at-color-bg) 1px,transparent 1px calc(100% - 1px)) center top,linear-gradient(transparent calc(100% - 1px),var(--at-color-bg) calc(100% - 1px) 1px) center bottom,linear-gradient(var(--at-color-border) 1px,transparent 1px calc(100% - 1px)) center top,linear-gradient(transparent calc(100% - 1px),var(--at-color-border) calc(100% - 1px) 1px) center bottom;background-repeat:no-repeat;background-color:transparent;background-size:100% 1px,100% 1px,100% 1px,100% 1px;background-attachment:local,local,scroll,scroll}.atk-comment-children>.atk-comment-wrap{margin-top:10px;border-left:1px dashed transparent;border-bottom-color:transparent}.atk-comment-children>.atk-comment-wrap:not(:last-child){margin-bottom:10px}.atk-comment-children>.atk-comment-wrap>.atk-comment{padding:0}.atk-comment-children>.atk-comment-wrap>.atk-comment>.atk-avatar img{width:36px;height:36px}.atk-comment-children>.atk-comment-wrap>.atk-comment>.atk-main{margin-left:47px}.artalk>.atk-list{position:relative}.artalk>.atk-list>.atk-list-header{display:flex;flex-direction:row;padding:10px 17px}.artalk>.atk-list>.atk-list-header .atk-text{display:inline-block}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap{position:relative;cursor:pointer}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-arrow-down-icon{cursor:pointer;vertical-align:middle;border-top:5px solid var(--at-color-grey);border-left:3px solid transparent;border-right:3px solid transparent;margin-top:-1px;margin-left:.8rem;display:inline-block}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap:hover .atk-dropdown{display:block}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown{z-index:3;display:none;height:auto!important;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;width:100%;background-color:var(--at-color-bg);padding:.6rem 0;border:1px solid var(--at-color-border);text-align:center;border-radius:6px;white-space:nowrap;margin:0;list-style:none}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item span,.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item a{display:block;line-height:2rem;position:relative;border-bottom:none;font-weight:400;padding:0 1.5rem}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item span:hover,.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item a:hover{color:var(--at-color-main)}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item.active span,.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item a{color:var(--at-color-main)}.artalk>.atk-list>.atk-list-header .atk-comment-count{font-size:15px}.artalk>.atk-list>.atk-list-header .atk-comment-count .atk-comment-count-num{font-size:22px;margin-right:4px}.artalk>.atk-list>.atk-list-header .atk-right-action{display:flex;flex:1;flex-direction:row;align-items:center;justify-content:flex-end}.artalk>.atk-list>.atk-list-header .atk-right-action>span{font-size:14px;color:var(--at-color-meta);cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:relative}.artalk>.atk-list>.atk-list-header .atk-right-action>span.atk-on,.artalk>.atk-list>.atk-list-header .atk-right-action>span.atk-on *{color:var(--at-color-main)}.artalk>.atk-list>.atk-list-header .atk-right-action>span:not(:last-child):not(.atk-hide){margin-right:10px;padding-right:10px}.artalk>.atk-list>.atk-list-header .atk-right-action>span .atk-unread-badge{position:absolute;top:-5px;left:-6px;color:#fff;background:var(--at-color-pink);text-align:center;min-width:16px;height:16px;padding:0 3px;border-radius:8px;line-height:16px;font-size:12px}.artalk>.atk-list>.atk-list-body{min-height:150px}.artalk>.atk-list>.atk-list-footer{text-align:right}@media only screen and (max-width: 768px){.artalk>.atk-list>.atk-list-footer{float:initial;text-align:center}}.artalk>.atk-list>.atk-list-footer .atk-copyright{display:block;font-size:12px;color:var(--at-color-meta);padding-right:15px}.artalk>.atk-list>.atk-list-footer .atk-copyright a{color:var(--at-color-main);text-decoration:none}.atk-list-no-comment{height:150px;display:flex;font-size:19px;justify-content:center;align-items:center;word-break:break-word;text-align:center}.atk-list-read-more{border-top:1px dashed var(--at-color-border);margin-top:28px;padding-bottom:25px}@media only screen and (max-width: 768px){.atk-list-read-more{padding-bottom:10px}}.atk-list-read-more.atk-err .atk-text{color:var(--at-color-red)!important}.atk-list-read-more .atk-list-read-more-inner{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:0 15px;font-size:14px;border-radius:6px;border:1px solid transparent;display:flex;height:30px;flex-direction:row;place-content:center;align-items:center;width:120px;margin:-15px auto 0;background:var(--at-color-bg);border-color:var(--at-color-border)}.atk-list-read-more .atk-list-read-more-inner>.atk-loading-icon{height:15px;width:15px}.atk-list-read-more .atk-list-read-more-inner>.atk-text{color:var(--at-color-meta)}.atk-list-read-more .atk-list-read-more-inner:hover{background:var(--at-color-bg-grey)}.atk-pagination{display:flex;flex-direction:row;justify-content:center;padding:10px 0;position:relative}.atk-pagination>.atk-btn,.atk-pagination>.atk-input{height:30px;border:1px solid var(--at-color-border);border-radius:3px;padding:0 5px;text-align:center;background:var(--at-color-bg)}.atk-pagination>.atk-btn{-webkit-user-select:none;-moz-user-select:none;user-select:none;width:60px;cursor:pointer;display:flex;justify-content:center;align-items:center}.atk-pagination>.atk-btn:hover{background:var(--at-color-bg-grey)}.atk-pagination>.atk-btn.atk-disabled{color:var(--at-color-sub)}.atk-pagination>.atk-btn.atk-disabled:hover{cursor:default;background:initial}.atk-pagination>.atk-input{background:transparent;color:var(--at-color-font);font-size:18px;width:60px;outline:none}.atk-pagination>.atk-input:focus{border-color:var(--at-color-main)}.atk-pagination>*:not(:last-child){margin-right:10px}.atk-main-editor{position:relative;overflow:hidden;background:var(--at-color-bg);border:1px solid var(--at-color-border);border-radius:6px;margin-bottom:10px}@media only screen and (max-width: 768px){.atk-main-editor{margin-bottom:7px}}.atk-main-editor.editor-traveling{margin-top:5px;margin-bottom:10px}.atk-main-editor>.atk-header{display:flex;flex-direction:row;padding:10px 14px 0}.atk-main-editor>.atk-header input{flex:1;width:100%;font-size:14px;background:transparent;border:2px solid transparent;border-radius:3px;padding:6px 5px;resize:none;outline:none}.atk-main-editor>.atk-header input:not(:last-child){margin-right:2px}.atk-main-editor>.atk-textarea-wrap{position:relative}.atk-main-editor>.atk-textarea-wrap>.atk-textarea{display:block;overflow:hidden;color:var(--at-color-font);font-size:15px;background-color:var(--at-color-bg);border:2px solid transparent;border-radius:3px;width:100%;min-height:120px;margin-top:2px;padding:10px 20px;resize:none;word-wrap:break-word;outline:none}.atk-main-editor>.atk-textarea-wrap>.atk-comment-closed{pointer-events:none;color:var(--at-color-meta);font-size:12px;background-color:var(--at-color-bg);border-top:1px solid var(--at-color-border);padding:5px 15px;margin-top:10px}.atk-main-editor>.atk-plug-panel-wrap{position:relative;height:180px;width:100%;overflow:hidden;border-top:1px solid var(--at-color-border);animation:.3s both atkFadeIn;transition:.2s height ease-in-out}.atk-main-editor>.atk-bottom{display:flex;flex-direction:row;row-gap:5px;justify-content:space-between;padding:5px;flex-wrap:wrap}.atk-main-editor>.atk-bottom>.atk-item{display:flex;flex-direction:row;align-items:center}.atk-main-editor>.atk-bottom>.atk-bottom-left>.atk-state-wrap{margin-right:5px}.atk-main-editor>.atk-bottom>.atk-bottom-left>.atk-plug-btn-wrap{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;row-gap:5px}.atk-main-editor>.atk-bottom .atk-plug-btn{display:flex;justify-content:center;place-items:center;padding:0 10px;line-height:30px;height:30px;cursor:pointer;color:var(--at-color-grey);font-size:14px;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:3px;word-break:keep-all}.atk-main-editor>.atk-bottom .atk-plug-btn:not(:last-child){margin-right:5px}.atk-main-editor>.atk-bottom .atk-plug-btn:hover{background:var(--at-color-bg-grey)}.atk-main-editor>.atk-bottom .atk-plug-btn.active{color:var(--at-color-main)}.atk-main-editor>.atk-bottom .atk-plug-btn.active svg.markdown path{fill:var(--at-color-main)}.atk-main-editor>.atk-bottom .atk-plug-btn i{display:flex;justify-content:center;place-items:center;color:var(--at-color-grey)}.atk-main-editor>.atk-bottom .atk-plug-btn i:not(:first-child){margin-left:4px}.atk-main-editor>.atk-bottom .atk-state-btn{z-index:2;height:30px;padding:0 0 0 10px;font-size:14px;position:relative;display:flex;flex-direction:row;justify-content:center;place-items:center;background:var(--at-color-bg-grey-transl);cursor:pointer;overflow:hidden;border-radius:3px}.atk-main-editor>.atk-bottom .atk-state-btn:hover .atk-cancel{background:#0000000a}@media only screen and (max-width: 768px){.atk-main-editor>.atk-bottom .atk-state-btn{padding:0}.atk-main-editor>.atk-bottom .atk-state-btn .atk-text-wrap{display:none}}.atk-main-editor>.atk-bottom .atk-state-btn .atk-text-wrap{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 8px 0 2px;max-width:8em}.atk-main-editor>.atk-bottom .atk-state-btn .atk-cancel{display:flex;justify-content:center;place-items:center;padding:0 10px;font-weight:700;height:100%;background:#00000005}.atk-main-editor>.atk-bottom .atk-send-btn{background:var(--at-color-main);color:#fff;font-size:14px;border:none;margin:0;height:30px;min-width:7.3em;cursor:pointer;transition:opacity .3s ease-in-out;outline:none;border-radius:3px}@media only screen and (max-width: 768px){.atk-main-editor>.atk-bottom .atk-send-btn{min-width:6em}}.atk-main-editor>.atk-bottom .atk-send-btn:active{opacity:.9}.atk-main-editor>.atk-notify-wrap{z-index:3;position:absolute;right:-2px;bottom:40px;width:225px;opacity:.83}.atk-sidebar-layer{position:fixed;z-index:99999;top:0;right:0;width:430px;height:100%;background:var(--at-color-bg);transition:transform .45s cubic-bezier(.23,1,.32,1) 0ms;transform:translate(430px)}@media only screen and (max-width: 430px){.atk-sidebar-layer{width:100%}}.atk-sidebar-layer .atk-sidebar-inner{position:relative;height:100%}.atk-sidebar-layer .atk-sidebar-header{position:absolute;top:0;right:0;display:flex;flex-direction:row;align-items:center;z-index:99999}.atk-sidebar-layer .atk-sidebar-header .atk-sidebar-close{display:flex;flex-direction:column;width:60px;height:60px;align-items:center;place-content:center;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-left:10px;font-size:22px}.atk-sidebar-layer .atk-sidebar-header .atk-sidebar-close:hover :after{background-color:#e81123e6}.atk-sidebar-layer .atk-sidebar-iframe-wrap{height:100%;position:relative}.atk-sidebar-layer .atk-sidebar-iframe-wrap iframe{border:0;width:100%;height:100%}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert{z-index:9999;top:50%;left:50%;transform:translate(-50%,-50%);position:absolute;background:var(--at-color-bg);padding:40px 30px;width:80%;text-align:center;border-radius:4px}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert .atk-title{font-size:1.4em;margin-bottom:20px;color:var(--at-color-font)}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert .atk-text{color:var(--at-color-font)}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert .atk-text span{cursor:pointer;color:var(--at-color-main)}.artalk{position:relative;width:100%;min-height:200px}.artalk,.atk-layer-wrap{color:var(--at-color-font);word-wrap:break-word;word-break:break-word}.artalk *,.atk-layer-wrap *{box-sizing:border-box}.artalk input,.artalk textarea,.artalk button,.artalk optgroup,.artalk select,.atk-layer-wrap input,.atk-layer-wrap textarea,.atk-layer-wrap button,.atk-layer-wrap optgroup,.atk-layer-wrap select{font-family:inherit;color:inherit;font-size:inherit}.artalk code,.atk-layer-wrap code{font-family:source code pro,Consolas,Monaco,Menlo,sans-serif;margin:0 .05em;padding:0 .4em;display:inline-block;vertical-align:middle;font-size:.9em;background-color:var(--at-color-bg-grey);color:var(--at-color-font);border-radius:2px}.artalk pre,.atk-layer-wrap pre{margin:10px 0 0;padding:0;line-height:0}.artalk pre code,.atk-layer-wrap pre code{line-height:1.6em;display:block;padding:10px 15px;white-space:pre-wrap!important;background-color:var(--at-color-bg-grey);color:var(--at-color-font);margin:0}.artalk pre code *,.atk-layer-wrap pre code *{font-family:source code pro,Consolas,Monaco,Menlo,sans-serif}.artalk a,.atk-layer-wrap a{color:var(--at-color-main);text-decoration:none}.artalk blockquote,.atk-layer-wrap blockquote{position:static;margin:10px 0;padding:10px 20px;background:var(--at-color-bg-grey);border-left:4px solid #687a86;color:var(--at-color-font)}.artalk p:first-child,.atk-layer-wrap p:first-child{margin-top:0}.artalk p:last-child,.atk-layer-wrap p:last-child{margin-bottom:0}.artalk img,.atk-layer-wrap img{max-width:100%}.artalk table,.atk-layer-wrap table{width:100%;border-collapse:collapse;border-spacing:0;margin-bottom:1.5em;font-size:.96em}.artalk td,.artalk th,.atk-layer-wrap td,.atk-layer-wrap th{text-align:left;padding:4px 8px 4px 10px;border:1px solid var(--at-color-border)}.artalk td,.atk-layer-wrap td{vertical-align:top}.artalk tr:nth-child(2n),.atk-layer-wrap tr:nth-child(2n){background-color:var(--at-color-bg-grey)}.artalk ul,.atk-layer-wrap ul{list-style:disc}.artalk ol,.atk-layer-wrap ol{list-style:decimal}.artalk li+li,.atk-layer-wrap li+li{margin-top:8px}.artalk li>ol,.artalk li>ul,.atk-layer-wrap li>ol,.atk-layer-wrap li>ul{margin:8px 0 0}.atk-hide{display:none!important}.atk-full-layer,.atk-layer-dialog-wrap,.atk-error-layer,.atk-loading{width:100%;height:100%;position:absolute;top:0;left:0;background:var(--at-color-bg);z-index:4;align-items:center;justify-content:center;flex-flow:column;display:flex}.atk-loading-spinner{position:relative;width:50px;height:50px}.atk-loading-spinner svg{animation:atkRotate 2s linear infinite;transform-origin:center center;width:100%;height:100%;position:absolute;top:0;left:0}.atk-loading-spinner svg circle{stroke-dasharray:1,200;stroke-dashoffset:0;animation:atkDash 1.5s ease-in-out infinite,atkColor 6s ease-in-out infinite;stroke-linecap:round}@keyframes atkRotate{to{transform:rotate(360deg)}}@keyframes atkDash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}to{stroke-dasharray:89,200;stroke-dashoffset:-124px}}@keyframes atkColor{0%,to{stroke:#ff5652}40%{stroke:#2196f3}66%{stroke:#32c787}80%,90%{stroke:#ffc107}}@keyframes atkLoadingIconRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.atk-loading-icon{width:18px;height:18px;box-sizing:border-box;border:solid 1px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;animation:atkLoadingIconRotate .4s linear infinite}.atk-fade-in{animation:atkFadeIn both .3s}.atk-fade-out{animation:atkFadeOut both .2s}.atk-rotate{animation:atkRotate 2s linear infinite}@keyframes atkFadeIn{0%{opacity:0}to{opacity:1}}@keyframes atkFadeOut{to{opacity:0}}@keyframes atkRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.atk-icon:after{display:block;content:"";width:1em;height:1em;background-color:var(--at-color-deep);background-size:contain;background-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;mask-size:contain}.atk-icon-sync:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.99133 4.87635C2.22512 7.64257 2.22512 12.1275 4.99133 14.8937C6.04677 15.9491 7.3524 16.6019 8.71732 16.8519' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M14.4179 15.4815L15.0072 14.8922C17.7734 12.126 17.7734 7.64107 15.0072 4.87486C13.9518 3.81942 12.6461 3.16668 11.2812 2.91664' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M6.17106 4.99252L5.58181 4.40327L4.99255 3.81401H6.17106V4.99252Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M13.8299 15.0084L14.4192 15.5976L15.0084 16.1869H13.8299V15.0084Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.99133 4.87635C2.22512 7.64257 2.22512 12.1275 4.99133 14.8937C6.04677 15.9491 7.3524 16.6019 8.71732 16.8519' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M14.4179 15.4815L15.0072 14.8922C17.7734 12.126 17.7734 7.64107 15.0072 4.87486C13.9518 3.81942 12.6461 3.16668 11.2812 2.91664' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M6.17106 4.99252L5.58181 4.40327L4.99255 3.81401H6.17106V4.99252Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M13.8299 15.0084L14.4192 15.5976L15.0084 16.1869H13.8299V15.0084Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E")}.atk-icon-del:after{background-color:var(--at-color-red)!important;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='22' height='22' viewBox='0 0 22 22' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.29167 5.04166L4.81251 5.04166M4.81251 5.04166L4.81251 18.3333C4.81251 18.5865 5.01771 18.7917 5.27084 18.7917L16.7292 18.7917C16.9823 18.7917 17.1875 18.5865 17.1875 18.3333V5.04166M4.81251 5.04166L7.33334 5.04166M17.1875 5.04166L19.7083 5.04166M17.1875 5.04166L14.6667 5.04166M7.33334 5.04166V3.20833L14.6667 3.20833V5.04166M7.33334 5.04166L14.6667 5.04166' stroke='%23D06565' stroke-width='2'/%3E%3Cpath d='M9.16667 8.25V15.125M12.8333 8.25V15.125' stroke='%23D06565' stroke-width='2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='22' height='22' viewBox='0 0 22 22' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.29167 5.04166L4.81251 5.04166M4.81251 5.04166L4.81251 18.3333C4.81251 18.5865 5.01771 18.7917 5.27084 18.7917L16.7292 18.7917C16.9823 18.7917 17.1875 18.5865 17.1875 18.3333V5.04166M4.81251 5.04166L7.33334 5.04166M17.1875 5.04166L19.7083 5.04166M17.1875 5.04166L14.6667 5.04166M7.33334 5.04166V3.20833L14.6667 3.20833V5.04166M7.33334 5.04166L14.6667 5.04166' stroke='%23D06565' stroke-width='2'/%3E%3Cpath d='M9.16667 8.25V15.125M12.8333 8.25V15.125' stroke='%23D06565' stroke-width='2'/%3E%3C/svg%3E")}.atk-icon-edit:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.70618 4.08515L12.6081 7.06376M1.00041 13.021L11.7376 2L14.6392 4.97861L3.90274 16H1L1.00041 13.021Z' stroke='%234E5969' stroke-width='1.5'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.70618 4.08515L12.6081 7.06376M1.00041 13.021L11.7376 2L14.6392 4.97861L3.90274 16H1L1.00041 13.021Z' stroke='%234E5969' stroke-width='1.5'/%3E%3C/svg%3E")}.atk-icon-yes:after,.atk-icon-check:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.7071 5.75533L9.92197 17.5404L3.29285 10.9113' stroke='%234E5969'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.7071 5.75533L9.92197 17.5404L3.29285 10.9113' stroke='%234E5969'/%3E%3C/svg%3E")}.atk-icon-plus:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.08331 10H17.9166' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M10 2.08334L10 17.9167' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.08331 10H17.9166' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M10 2.08334L10 17.9167' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E")}.atk-icon-close-slim:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='25' height='25' viewBox='0 0 25 25' fill='none'%3E%3Cpath d='M19.8657 5.13431L12.5 12.5L5.13431 19.8657' stroke='%234E5969'/%3E%3Cpath d='M5.13431 5.13432L12.5 12.5L19.8657 19.8657' stroke='%234E5969'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='25' height='25' viewBox='0 0 25 25' fill='none'%3E%3Cpath d='M19.8657 5.13431L12.5 12.5L5.13431 19.8657' stroke='%234E5969'/%3E%3Cpath d='M5.13431 5.13432L12.5 12.5L19.8657 19.8657' stroke='%234E5969'/%3E%3C/svg%3E")}.atk-icon-arrow-left:after{-webkit-mask-image:url('data:image/svg+xml,');mask-image:url('data:image/svg+xml,')}.atk-icon-no:after,.atk-icon-close:after{-webkit-mask-image:url('data:image/svg+xml,');mask-image:url('data:image/svg+xml,')}.atk-error-layer{background-color:var(--at-color-bg-transl)}.atk-error-layer .atk-error-title{color:var(--at-color-red)}.atk-error-layer .atk-warn-title{color:var(--at-color-yellow)}.atk-error-layer .atk-error-title,.atk-error-layer .atk-warn-title{display:inline-block;padding:0 15px;margin-bottom:20px;font-size:20px;letter-spacing:-.5px}.atk-error-layer .atk-error-text{text-align:center;padding:0 20px}.atk-error-layer .atk-error-text *{color:var(--at-color-deep)}.atk-error-layer .atk-error-text a{color:var(--at-color-meta)}.atk-version-check-notice{background:var(--at-color-bg-grey);border-radius:6px;padding:10px 20px;margin-bottom:10px;font-size:14px}.atk-version-check-notice .atk-info{color:var(--at-color-meta)}.atk-version-check-notice .atk-ignore-btn{cursor:pointer;float:right}.atk-version-check-notice .atk-ignore-btn:hover{opacity:.8}.atk-layer-dialog-wrap{background-color:var(--at-color-bg-transl)}.atk-layer-dialog-wrap>.atk-layer-dialog{width:25%}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-content .atk-captcha-img{cursor:pointer;width:170px;height:auto;margin-right:10px;padding-right:10px;border-right:1px solid var(--at-color-border);vertical-align:bottom}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-content input{width:100%;line-height:34px;background-color:var(--at-color-bg);border:1px solid var(--at-color-border);border-radius:3px;outline:none;padding:0 6px;display:block;margin-top:10px;margin-bottom:5px;text-align:center}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions{display:flex;flex-direction:row}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button{flex:1;display:block;cursor:pointer;border:1px solid var(--at-color-main);background:transparent;color:var(--at-color-main);border-radius:3px;padding:0 15px;line-height:30px;outline:none}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button:active{color:#fff;background:var(--at-color-main)}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button:not(:last-child){margin-right:5px}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button.error{color:#fff;background:#ff5652;border-color:#ff5652}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap{position:fixed;z-index:999998;left:0;top:0;height:100vh;width:100vw}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap>iframe{width:100%;height:100%;border:0}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap .atk-close-btn{z-index:999999;position:fixed;top:20px;right:20px;display:flex;flex-direction:column;width:50px;height:50px;align-items:center;place-content:center;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-left:10px}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap .atk-close-btn:hover .atk-icon-close:after{background-color:#e81123e6}@media only screen and (max-width: 768px){.atk-layer-dialog-wrap>.atk-layer-dialog{width:90%!important}}.atk-notify{display:block;overflow:hidden;background-color:#2c2c2c;color:#fff;border-radius:3px;cursor:pointer;font-size:14px;padding:5px 15px}.atk-notify:not(:last-child){margin-bottom:3px}.atk-notify .atk-notify-content{color:#fff}.atk-layer-wrap .atk-layer-mask{position:fixed;top:0;left:0;width:100%;height:100%;z-index:99998;background:#0000004d}.atk-layer-wrap .atk-layer-item{position:fixed;z-index:99999;top:0;right:0;width:100%;height:100%}.atk-common-action-btn.atk-btn-confirm,.atk-common-action-btn.atk-btn-warn{color:var(--at-color-yellow)!important}.atk-common-action-btn.atk-btn-error{color:var(--at-color-red)!important}.atk-common-action-btn.atk-btn-success{color:var(--at-color-green)!important}img[atk-emoticon]{max-height:60px;display:initial}.atk-slim-scrollbar::-webkit-scrollbar,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar{width:4px;height:4px;background:transparent}.atk-slim-scrollbar::-webkit-scrollbar-thumb,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar-thumb,.atk-slim-scrollbar::-webkit-scrollbar-thumb:window-inactive{background:#5656564d}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:hover,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar-thumb:vertical:hover{background:#414a52c4}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:active,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar-thumb:vertical:active{background:#292f35c4}.atk-editor-plug-emoticons{height:100%;width:100%}.atk-editor-plug-emoticons>.atk-grp-wrap{overflow-y:scroll;overflow-x:hidden;height:100%;width:100%}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp{display:flex;flex-wrap:wrap;flex-direction:row;padding:5px 10px 35px}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp[data-type=image]>.atk-item{height:63px;width:63px}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp>.atk-item{display:flex;align-items:center;justify-content:center;padding:5px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:3px;font-size:15px;min-width:35px;margin:2px}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp>.atk-item>img{max-height:100%;width:auto}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp>.atk-item:hover{background:var(--at-color-bg-grey)}.atk-editor-plug-emoticons>.atk-grp-switcher{position:absolute;bottom:0;left:0;width:100%;background:var(--at-color-bg-transl);height:30px;border-top:1px solid var(--at-color-border);border-bottom:1px solid var(--at-color-border)}.atk-editor-plug-emoticons>.atk-grp-switcher>span{-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:0 10px;line-height:30px;float:left;display:block;cursor:pointer;font-size:14px}.atk-editor-plug-emoticons>.atk-grp-switcher>span:hover,.atk-editor-plug-emoticons>.atk-grp-switcher>span.active{background:var(--at-color-bg-grey)}.atk-slim-scrollbar::-webkit-scrollbar{width:4px;height:4px;background:transparent}.atk-slim-scrollbar::-webkit-scrollbar-thumb,.atk-slim-scrollbar::-webkit-scrollbar-thumb:window-inactive{background:#5656564d}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:hover{background:#414a52c4}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:active{background:#292f35c4}.atk-editor-plug-preview{overflow-y:scroll;overflow-x:hidden;height:100%;width:100%;padding:10px 15px} diff --git a/blog-admin/public/dist/Artalk.js b/blog-admin/public/dist/Artalk.js new file mode 100644 index 00000000..137502df --- /dev/null +++ b/blog-admin/public/dist/Artalk.js @@ -0,0 +1,11 @@ +!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,s,i,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(((s,i)=>{var r=e=>{try{a(n.next(e))}catch(t){i(t)}},o=e=>{try{a(n.throw(e))}catch(t){i(t)}},a=e=>e.done?s(e.value):Promise.resolve(e.value).then(r,o);a((n=n.apply(e,t)).next())}));class y{constructor(e={}){g(this,"baseUrl","/api/v2"),g(this,"securityData",null),g(this,"securityWorker"),g(this,"abortControllers",new Map),g(this,"customFetch",((...e)=>fetch(...e))),g(this,"baseApiParams",{credentials:"same-origin",headers:{},redirect:"follow",referrerPolicy:"no-referrer"}),g(this,"setSecurityData",(e=>{this.securityData=e})),g(this,"contentFormatters",{"application/json":e=>null===e||"object"!=typeof e&&"string"!=typeof e?e:JSON.stringify(e),"text/plain":e=>null!==e&&"string"!=typeof e?JSON.stringify(e):e,"multipart/form-data":e=>Object.keys(e||{}).reduce(((t,n)=>{const s=e[n];return t.append(n,s instanceof Blob?s:"object"==typeof s&&null!==s?JSON.stringify(s):`${s}`),t}),new FormData),"application/x-www-form-urlencoded":e=>this.toQueryString(e)}),g(this,"createAbortSignal",(e=>{if(this.abortControllers.has(e)){const t=this.abortControllers.get(e);return t?t.signal:void 0}const t=new AbortController;return this.abortControllers.set(e,t),t.signal})),g(this,"abortRequest",(e=>{const t=this.abortControllers.get(e);t&&(t.abort(),this.abortControllers.delete(e))})),g(this,"request",(e=>k(this,null,(function*(){var t=e,{body:n,secure:s,path:i,type:r,query:o,format:a,baseUrl:h,cancelToken:g}=t,m=((e,t)=>{var n={};for(var s in e)c.call(e,s)&&t.indexOf(s)<0&&(n[s]=e[s]);if(null!=e&&l)for(var s of l(e))t.indexOf(s)<0&&d.call(e,s)&&(n[s]=e[s]);return n})(t,["body","secure","path","type","query","format","baseUrl","cancelToken"]);const f=("boolean"==typeof s?s:this.baseApiParams.secure)&&this.securityWorker&&(yield this.securityWorker(this.securityData))||{},y=this.mergeRequestParams(m,f),v=o&&this.toQueryString(o),$=this.contentFormatters[r||"application/json"],b=a||y.format;return this.customFetch(`${h||this.baseUrl||""}${i}${v?`?${v}`:""}`,p(u({},y),{headers:u(u({},y.headers||{}),r&&"multipart/form-data"!==r?{"Content-Type":r}:{}),signal:(g?this.createAbortSignal(g):y.signal)||null,body:null==n?null:$(n)})).then((e=>k(this,null,(function*(){const t=e;t.data=null,t.error=null;const n=b?yield e[b]().then((e=>(t.ok?t.data=e:t.error=e,t))).catch((e=>(t.error=e,t))):t;if(g&&this.abortControllers.delete(g),!e.ok)throw n;return n}))))})))),Object.assign(this,e)}encodeQueryParam(e,t){return`${encodeURIComponent(e)}=${encodeURIComponent("number"==typeof t?t:`${t}`)}`}addQueryParam(e,t){return this.encodeQueryParam(t,e[t])}addArrayQueryParam(e,t){return e[t].map((e=>this.encodeQueryParam(t,e))).join("&")}toQueryString(e){const t=e||{};return Object.keys(t).filter((e=>void 0!==t[e])).map((e=>Array.isArray(t[e])?this.addArrayQueryParam(t,e):this.addQueryParam(t,e))).join("&")}addQueryParams(e){const t=this.toQueryString(e);return t?`?${t}`:""}mergeRequestParams(e,t){return p(u(u(u({},this.baseApiParams),e),t||{}),{headers:u(u(u({},this.baseApiParams.headers||{}),e.headers||{}),t&&t.headers||{})})}} +/** + * @title Artalk API + * @version 2.0 + * @license MIT (https://github.com/ArtalkJS/Artalk/blob/master/LICENSE) + * @baseUrl /api/v2 + * @contact API Support (https://artalk.js.org) + * + * Artalk is a modern comment system based on Golang. + */let v=class extends y{constructor(){super(...arguments),g(this,"auth",{loginByEmail:(e,t={})=>this.request(u({path:"/auth/email/login",method:"POST",body:e,type:"application/json",format:"json"},t)),registerByEmail:(e,t={})=>this.request(u({path:"/auth/email/register",method:"POST",body:e,type:"application/json",format:"json"},t)),sendVerifyEmail:(e,t={})=>this.request(u({path:"/auth/email/send",method:"POST",body:e,type:"application/json",format:"json"},t)),checkDataMerge:(e={})=>this.request(u({path:"/auth/merge",method:"GET",secure:!0,format:"json"},e)),applyDataMerge:(e,t={})=>this.request(u({path:"/auth/merge",method:"POST",body:e,secure:!0,type:"application/json",format:"json"},t))}),g(this,"cache",{flushCache:(e={})=>this.request(u({path:"/cache/flush",method:"POST",secure:!0,format:"json"},e)),warmUpCache:(e={})=>this.request(u({path:"/cache/warm_up",method:"POST",secure:!0,format:"json"},e))}),g(this,"captcha",{getCaptcha:(e={})=>this.request(u({path:"/captcha",method:"GET",format:"json"},e)),getCaptchaStatus:(e={})=>this.request(u({path:"/captcha/status",method:"GET",format:"json"},e)),verifyCaptcha:(e,t={})=>this.request(u({path:"/captcha/verify",method:"POST",body:e,type:"application/json",format:"json"},t))}),g(this,"comments",{getComments:(e,t={})=>this.request(u({path:"/comments",method:"GET",query:e,secure:!0,type:"application/json",format:"json"},t)),createComment:(e,t={})=>this.request(u({path:"/comments",method:"POST",body:e,secure:!0,type:"application/json",format:"json"},t)),getComment:(e,t={})=>this.request(u({path:`/comments/${e}`,method:"GET",type:"application/json",format:"json"},t)),updateComment:(e,t,n={})=>this.request(u({path:`/comments/${e}`,method:"PUT",body:t,secure:!0,type:"application/json",format:"json"},n)),deleteComment:(e,t={})=>this.request(u({path:`/comments/${e}`,method:"DELETE",secure:!0,format:"json"},t))}),g(this,"conf",{conf:(e={})=>this.request(u({path:"/conf",method:"GET",format:"json"},e)),getSocialLoginProviders:(e={})=>this.request(u({path:"/conf/auth/providers",method:"GET",format:"json"},e)),getDomain:(e,t={})=>this.request(u({path:"/conf/domain",method:"GET",query:e,format:"json"},t))}),g(this,"notifies",{getNotifies:(e,t={})=>this.request(u({path:"/notifies",method:"GET",query:e,type:"application/json",format:"json"},t)),markAllNotifyRead:(e,t={})=>this.request(u({path:"/notifies/read",method:"POST",body:e,type:"application/json",format:"json"},t)),markNotifyRead:(e,t,n={})=>this.request(u({path:`/notifies/${e}/${t}`,method:"POST",format:"json"},n))}),g(this,"pages",{getPages:(e,t={})=>this.request(u({path:"/pages",method:"GET",query:e,secure:!0,type:"application/json",format:"json"},t)),fetchAllPages:(e,t={})=>this.request(u({path:"/pages/fetch",method:"POST",body:e,secure:!0,type:"application/json",format:"json"},t)),getPageFetchStatus:(e={})=>this.request(u({path:"/pages/fetch/status",method:"GET",secure:!0,format:"json"},e)),logPv:(e,t={})=>this.request(u({path:"/pages/pv",method:"POST",body:e,type:"application/json",format:"json"},t)),updatePage:(e,t,n={})=>this.request(u({path:`/pages/${e}`,method:"PUT",body:t,secure:!0,type:"application/json",format:"json"},n)),deletePage:(e,t={})=>this.request(u({path:`/pages/${e}`,method:"DELETE",secure:!0,format:"json"},t)),fetchPage:(e,t={})=>this.request(u({path:`/pages/${e}/fetch`,method:"POST",secure:!0,type:"application/json",format:"json"},t))}),g(this,"sendEmail",{sendEmail:(e,t={})=>this.request(u({path:"/send_email",method:"POST",body:e,secure:!0,type:"application/json",format:"json"},t))}),g(this,"settings",{getSettings:(e={})=>this.request(u({path:"/settings",method:"GET",secure:!0,format:"json"},e)),applySettings:(e,t={})=>this.request(u({path:"/settings",method:"PUT",body:e,secure:!0,type:"application/json",format:"json"},t)),getSettingsTemplate:(e,t={})=>this.request(u({path:`/settings/template/${e}`,method:"GET",secure:!0,format:"json"},t))}),g(this,"sites",{getSites:(e={})=>this.request(u({path:"/sites",method:"GET",secure:!0,format:"json"},e)),createSite:(e,t={})=>this.request(u({path:"/sites",method:"POST",body:e,secure:!0,type:"application/json",format:"json"},t)),updateSite:(e,t,n={})=>this.request(u({path:`/sites/${e}`,method:"PUT",body:t,secure:!0,type:"application/json",format:"json"},n)),deleteSite:(e,t={})=>this.request(u({path:`/sites/${e}`,method:"DELETE",secure:!0,format:"json"},t))}),g(this,"stats",{getStats:(e,t,n={})=>this.request(u({path:`/stats/${e}`,method:"GET",query:t,type:"application/json",format:"json"},n))}),g(this,"transfer",{exportArtrans:(e={})=>this.request(u({path:"/transfer/export",method:"GET",secure:!0,format:"json"},e)),importArtrans:(e,t={})=>this.request(u({path:"/transfer/import",method:"POST",body:e,secure:!0,type:"application/json"},t)),uploadArtrans:(e,t={})=>this.request(u({path:"/transfer/upload",method:"POST",body:e,secure:!0,type:"multipart/form-data",format:"json"},t))}),g(this,"upload",{upload:(e,t={})=>this.request(u({path:"/upload",method:"POST",body:e,secure:!0,type:"multipart/form-data",format:"json"},t))}),g(this,"user",{getUser:(e,t={})=>this.request(u({path:"/user",method:"GET",query:e,secure:!0,format:"json"},t)),login:(e,t={})=>this.request(u({path:"/user/access_token",method:"POST",body:e,type:"application/json",format:"json"},t)),getUserStatus:(e,t={})=>this.request(u({path:"/user/status",method:"GET",query:e,secure:!0,format:"json"},t))}),g(this,"users",{createUser:(e,t={})=>this.request(u({path:"/users",method:"POST",body:e,secure:!0,type:"application/json",format:"json"},t)),updateUser:(e,t,n={})=>this.request(u({path:`/users/${e}`,method:"PUT",body:t,secure:!0,type:"application/json",format:"json"},n)),deleteUser:(e,t={})=>this.request(u({path:`/users/${e}`,method:"DELETE",secure:!0,format:"json"},t)),getUsers:(e,t,n={})=>this.request(u({path:`/users/${e}`,method:"GET",query:t,secure:!0,type:"application/json",format:"json"},n))}),g(this,"version",{getVersion:(e={})=>this.request(u({path:"/version",method:"GET",format:"json"},e))}),g(this,"votes",{syncVotes:(e={})=>this.request(u({path:"/votes/sync",method:"POST",secure:!0,format:"json"},e)),vote:(e,t,n,s={})=>this.request(u({path:`/votes/${e}/${t}`,method:"POST",body:n,type:"application/json",format:"json"},s))})}};var $="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function b(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;nk(this,null,(function*(){const s=e.getApiToken&&e.getApiToken(),i=new Headers(u({Authorization:s?`Bearer ${s}`:""},null==n?void 0:n.headers));i.get("Authorization")||i.delete("Authorization");const r=yield fetch(t,p(u({},n),{headers:i}));if(!r.ok){const s=(yield r.json().catch((()=>{})))||{};let i=!1;if(e.handlers&&(yield e.handlers.get().reduce(((e,t)=>k(this,null,(function*(){yield e,!0===s[t.action]&&(yield t.handler(s),i=!0)}))),Promise.resolve())),i)return w(e,t,n);throw function(e,t){const n=new x;return n.message=t.msg||t.message||"fetch error",n.code=e,n.data=t,console.error(n),n}(r.status,s)}return r}));class x extends Error{constructor(){super(...arguments),g(this,"code",0),g(this,"message","fetch error"),g(this,"data")}}class C extends v{constructor(e){super({baseUrl:e.baseURL,customFetch:(t,n)=>w(e,t,n)}),g(this,"_opts"),this._opts=e}getUserFields(){const e=this._opts.userInfo;if((null==e?void 0:e.name)&&(null==e?void 0:e.email))return{name:e.name,email:e.email}}}function E(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}let S={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};function T(e){S=e}const A=/[&<>"']/,L=new RegExp(A.source,"g"),P=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,R=new RegExp(P.source,"g"),M={"&":"&","<":"<",">":">",'"':""","'":"'"},O=e=>M[e];function I(e,t){if(t){if(A.test(e))return e.replace(L,O)}else if(P.test(e))return e.replace(R,O);return e}const _=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;const U=/(^|[^\[])\^/g;function q(e,t){let n="string"==typeof e?e:e.source;t=t||"";const s={replace:(e,t)=>{let i="string"==typeof t?t:t.source;return i=i.replace(U,"$1"),n=n.replace(e,i),s},getRegex:()=>new RegExp(n,t)};return s}function j(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(t){return null}return e}const D={exec:()=>null};function B(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,i=t;for(;--i>=0&&"\\"===n[i];)s=!s;return s?"|":" |"})).split(/ \|/);let s=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.length0)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:F(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 s=n[1];return t.split("\n").map((e=>{const t=e.match(/^\s+/);if(null===t)return e;const[n]=t;return n.length>=s.length?e.slice(s.length):e})).join("\n")}(e,t[3]||"");return{type:"code",raw:e,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$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=F(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){let e=t[0].replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,"\n $1");e=F(e.replace(/^ *>[ \t]?/gm,""),"\n");const n=this.lexer.state.top;this.lexer.state.top=!0;const s=this.lexer.blockTokens(e);return this.lexer.state.top=n,{type:"blockquote",raw:t[0],tokens:s,text:e}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();const s=n.length>1,i={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=s?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 s=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=s.trimStart()):(d=t[2].search(/[^ ]/),d=d>4?1:d,a=s.slice(d),d+=t[1].length);let h=!1;if(!s&&/^ *$/.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+|$)`),i=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," ")),i.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(s.search(/[^ ]/)>=4)break;if(i.test(s))break;if(r.test(s))break;if(n.test(s))break;a+="\n"+c}h||c.trim()||(h=!0),o+=l+"\n",e=e.substring(l.length+1),s=c.slice(d)}}i.loose||(l?i.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]\] +/,""))),i.items.push({type:"list_item",raw:o,task:!!p,checked:u,loose:!1,text:a,tokens:[]}),i.raw+=o}i.items[i.items.length-1].raw=o.trimEnd(),i.items[i.items.length-1].text=a.trimEnd(),i.raw=i.raw.trimEnd();for(let e=0;e"space"===e.type)),n=t.length>0&&t.some((e=>/\n.*\n/.test(e.raw)));i.loose=n}if(i.loose)for(let e=0;e$/,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",s=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return{type:"def",tag:e,raw:t[0],href:n,title:s}}}table(e){const t=this.rules.block.table.exec(e);if(!t)return;if(!/[:|]/.test(t[2]))return;const n=B(t[1]),s=t[2].replace(/^\||\| *$/g,"").split("|"),i=t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[],r={type:"table",raw:t[0],header:[],align:[],rows:[]};if(n.length===s.length){for(const e of s)/^ *-+: *$/.test(e)?r.align.push("right"):/^ *:-+: *$/.test(e)?r.align.push("center"):/^ *:-+ *$/.test(e)?r.align.push("left"):r.align.push(null);for(const e of n)r.header.push({text:e,tokens:this.lexer.inline(e)});for(const e of i)r.rows.push(B(e,r.header.length).map((e=>({text:e,tokens:this.lexer.inline(e)}))));return r}}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:I(t[1])}}tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&/^/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&/^$/.test(e))return;const t=F(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 s=0;s-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],s="";if(this.options.pedantic){const e=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n);e&&(n=e[1],s=e[3])}else s=t[3]?t[3].slice(1,-1):"";return n=n.trim(),/^$/.test(e)?n.slice(1):n.slice(1,-1)),N(t,{href:n?n.replace(this.rules.inline.anyPunctuation,"$1"):n,title:s?s.replace(this.rules.inline.anyPunctuation,"$1"):s},t[0],this.lexer)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){const e=t[(n[2]||n[1]).replace(/\s+/g," ").toLowerCase()];if(!e){const e=n[0].charAt(0);return{type:"text",raw:e,text:e}}return N(n,e,n[0],this.lexer)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(!s)return;if(s[3]&&n.match(/[\p{L}\p{N}]/u))return;if(!(s[1]||s[2]||"")||!n||this.rules.inline.punctuation.exec(n)){const n=[...s[0]].length-1;let i,r,o=n,a=0;const l="*"===s[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(l.lastIndex=0,t=t.slice(-1*e.length+n);null!=(s=l.exec(t));){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i)continue;if(r=[...i].length,s[3]||s[4]){o+=r;continue}if((s[5]||s[6])&&n%3&&!((n+r)%3)){a+=r;continue}if(o-=r,o>0)continue;r=Math.min(r,r+o+a);const t=[...s[0]][0].length,l=e.slice(0,n+s.index+t+r);if(Math.min(n,r)%2){const e=l.slice(1,-1);return{type:"em",raw:l,text:e,tokens:this.lexer.inlineTokens(e)}}const c=l.slice(2,-2);return{type:"strong",raw:l,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(/\n/g," ");const n=/[^ ]/.test(e),s=/^ /.test(e)&&/ $/.test(e);return n&&s&&(e=e.substring(1,e.length-1)),e=I(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){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;return"@"===t[2]?(e=I(t[1]),n="mailto:"+e):(e=I(t[1]),n=e),{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}url(e){var t,n;let s;if(s=this.rules.inline.url.exec(e)){let e,i;if("@"===s[2])e=I(s[0]),i="mailto:"+e;else{let r;do{r=s[0],s[0]=null!=(n=null==(t=this.rules.inline._backpedal.exec(s[0]))?void 0:t[0])?n:""}while(r!==s[0]);e=I(s[0]),i="www."===s[1]?"http://"+s[0]:s[0]}return{type:"link",raw:s[0],text:e,href:i,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;return e=this.lexer.state.inRawBlock?t[0]:I(t[0]),{type:"text",raw:t[0],text:e}}}}const z=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,H=/(?:[*+-]|\d{1,9}[.)])/,Q=q(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g,H).replace(/blockCode/g,/ {4}/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).getRegex(),V=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,G=/(?!\s*\])(?:\\.|[^\[\]\\])+/,K=q(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/).replace("label",G).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Z=q(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,H).getRegex(),Y="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|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",X=/|$))/,J=q("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))","i").replace("comment",X).replace("tag",Y).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),ee=q(V).replace("hr",z).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Y).getRegex(),te={blockquote:q(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",ee).getRegex(),code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,def:K,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:z,html:J,lheading:Q,list:Z,newline:/^(?: *(?:\n|$))+/,paragraph:ee,table:D,text:/^[^\n]+/},ne=q("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",z).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Y).getRegex(),se=p(u({},te),{table:ne,paragraph:q(V).replace("hr",z).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",ne).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Y).getRegex()}),ie=p(u({},te),{html:q("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",X).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:D,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:q(V).replace("hr",z).replace("heading"," *#{1,6} *[^\n]").replace("lheading",Q).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()}),re=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,oe=/^( {2,}|\\)\n(?!\s*$)/,ae="\\p{P}\\p{S}",le=q(/^((?![*_])[\spunctuation])/,"u").replace(/punctuation/g,ae).getRegex(),ce=q(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,"u").replace(/punct/g,ae).getRegex(),de=q("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])","gu").replace(/punct/g,ae).getRegex(),he=q("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])","gu").replace(/punct/g,ae).getRegex(),ue=q(/\\([punct])/,"gu").replace(/punct/g,ae).getRegex(),pe=q(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("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])?)+(?![-_])/).getRegex(),ge=q(X).replace("(?:--\x3e|$)","--\x3e").getRegex(),me=q("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",ge).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),fe=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,ke=q(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",fe).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),ye=q(/^!?\[(label)\]\[(ref)\]/).replace("label",fe).replace("ref",G).getRegex(),ve=q(/^!?\[(ref)\](?:\[\])?/).replace("ref",G).getRegex(),$e={_backpedal:D,anyPunctuation:ue,autolink:pe,blockSkip:/\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g,br:oe,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:D,emStrongLDelim:ce,emStrongRDelimAst:de,emStrongRDelimUnd:he,escape:re,link:ke,nolink:ve,punctuation:le,reflink:ye,reflinkSearch:q("reflink|nolink(?!\\()","g").replace("reflink",ye).replace("nolink",ve).getRegex(),tag:me,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\t+" ".repeat(n.length)));e;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some((s=>!!(n=s.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),s=t[t.length-1],!s||"paragraph"!==s.type&&"text"!==s.type?t.push(n):(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=s.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),s=t[t.length-1],!s||"paragraph"!==s.type&&"text"!==s.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(s.raw+="\n"+n.raw,s.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=s.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(i=e,this.options.extensions&&this.options.extensions.startBlock){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startBlock.forEach((e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))})),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(this.state.top&&(n=this.tokenizer.paragraph(i)))s=t[t.length-1],r&&"paragraph"===s.type?(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=s.text):t.push(n),r=i.length!==e.length,e=e.substring(n.raw.length);else if(n=this.tokenizer.text(e))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===s.type?(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=s.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,s,i,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((s=>!!(n=s.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),s=t[t.length-1],s&&"text"===n.type&&"text"===s.type?(s.raw+=n.raw,s.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),s=t[t.length-1],s&&"text"===n.type&&"text"===s.type?(s.raw+=n.raw,s.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))e=e.substring(n.raw.length),t.push(n);else if(this.state.inLink||!(n=this.tokenizer.url(e))){if(i=e,this.options.extensions&&this.options.extensions.startInline){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startInline.forEach((e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))})),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(n=this.tokenizer.inlineText(i))e=e.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(a=n.raw.slice(-1)),o=!0,s=t[t.length-1],s&&"text"===s.type?(s.raw+=n.raw,s.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 Te{constructor(e){g(this,"options"),this.options=e||S}code(e,t,n){var s;const i=null==(s=(t||"").match(/^\S*/))?void 0:s[0];return e=e.replace(/\n$/,"")+"\n",i?'
'+(n?e:I(e,!0))+"
\n":"
"+(n?e:I(e,!0))+"
\n"}blockquote(e){return`
\n${e}
\n`}html(e,t){return e}heading(e,t,n){return`${e}\n`}hr(){return"
\n"}list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"\n"}listitem(e,t,n){return`
  • ${e}
  • \n`}checkbox(e){return"'}paragraph(e){return`

    ${e}

    \n`}table(e,t){return t&&(t=`${t}`),"\n\n"+e+"\n"+t+"
    \n"}tablerow(e){return`\n${e}\n`}tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`\n`}strong(e){return`${e}`}em(e){return`${e}`}codespan(e){return`${e}`}br(){return"
    "}del(e){return`${e}`}link(e,t,n){const s=j(e);if(null===s)return n;let i='
    ",i}image(e,t,n){const s=j(e);if(null===s)return n;let i=`${n}"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):"")));continue}case"code":{const e=i;n+=this.renderer.code(e.text,e.lang,!!e.escaped);continue}case"table":{const e=i;let t="",s="";for(let n=0;n0&&"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,i,!!s)}n+=this.renderer.list(o,t,s);continue}case"html":{const e=i;n+=this.renderer.html(e.text,e.block);continue}case"paragraph":{const e=i;n+=this.renderer.paragraph(this.parseInline(e.tokens));continue}case"text":{let r=i,o=r.tokens?this.parseInline(r.tokens):r.text;for(;s+1{const o=u({},r),a=u(u({},this.defaults),o);!0===this.defaults.async&&!1===o.async&&(a.silent||console.warn("marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored."),a.async=!0);const l=f(this,s,i).call(this,!!a.silent,!!a.async);if(null==n)return l(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof n)return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(a.hooks&&(a.hooks.options=a),a.async)return Promise.resolve(a.hooks?a.hooks.preprocess(n):n).then((t=>e(t,a))).then((e=>a.hooks?a.hooks.processAllTokens(e):e)).then((e=>a.walkTokens?Promise.all(this.walkTokens(e,a.walkTokens)).then((()=>e)):e)).then((e=>t(e,a))).then((e=>a.hooks?a.hooks.postprocess(e):e)).catch(l);try{a.hooks&&(n=a.hooks.preprocess(n));let s=e(n,a);a.hooks&&(s=a.hooks.processAllTokens(s)),a.walkTokens&&this.walkTokens(s,a.walkTokens);let i=t(s,a);return a.hooks&&(i=a.hooks.postprocess(i)),i}catch(c){return l(c)}}},s=new WeakSet,i=function(e,t){return n=>{if(n.message+="\nPlease report this to https://github.com/markedjs/marked.",e){const e="

    An error occurred:

    "+I(n.message+"",!0)+"
    ";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}};const Re=new class{constructor(...e){m(this,t),m(this,s),g(this,"defaults",{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}),g(this,"options",this.setOptions),g(this,"parse",f(this,t,n).call(this,Se.lex,Le.parse)),g(this,"parseInline",f(this,t,n).call(this,Se.lexInline,Le.parseInline)),g(this,"Parser",Le),g(this,"Renderer",Te),g(this,"TextRenderer",Ae),g(this,"Lexer",Se),g(this,"Tokenizer",W),g(this,"Hooks",Pe),this.use(...e)}walkTokens(e,t){var n,s;let i=[];for(const r of e)switch(i=i.concat(t.call(this,r)),r.type){case"table":{const e=r;for(const n of e.header)i=i.concat(this.walkTokens(n.tokens,t));for(const n of e.rows)for(const e of n)i=i.concat(this.walkTokens(e.tokens,t));break}case"list":{const e=r;i=i.concat(this.walkTokens(e.items,t));break}default:{const e=r;(null==(s=null==(n=this.defaults.extensions)?void 0:n.childTokens)?void 0:s[e.type])?this.defaults.extensions.childTokens[e.type].forEach((n=>{const s=e[n].flat(1/0);i=i.concat(this.walkTokens(s,t))})):e.tokens&&(i=i.concat(this.walkTokens(e.tokens,t)))}}return i}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 s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}: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 Te(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(`renderer '${n}' does not exist`);if("options"===n)continue;const s=n,i=e.renderer[s],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 W(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(`tokenizer '${n}' does not exist`);if(["options","rules","lexer"].includes(n))continue;const s=n,i=e.tokenizer[s],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 Pe;for(const n in e.hooks){if(!(n in t))throw new Error(`hook '${n}' does not exist`);if("options"===n)continue;const s=n,i=e.hooks[s],r=t[s];Pe.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,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.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}lexer(e,t){return Se.lex(e,null!=t?t:this.defaults)}parser(e,t){return Le.parse(e,null!=t?t:this.defaults)}};function Me(e,t){return Re.parse(e,t)}Me.options=Me.setOptions=function(e){return Re.setOptions(e),Me.defaults=Re.defaults,T(Me.defaults),Me},Me.getDefaults=E,Me.defaults=S,Me.use=function(...e){return Re.use(...e),Me.defaults=Re.defaults,T(Me.defaults),Me},Me.walkTokens=function(e,t){return Re.walkTokens(e,t)},Me.parseInline=Re.parseInline,Me.Parser=Le,Me.parser=Le.parse,Me.Renderer=Te,Me.TextRenderer=Ae,Me.Lexer=Se,Me.lexer=Se.lex,Me.Tokenizer=W,Me.Hooks=Pe,Me.parse=Me,Me.options,Me.setOptions,Me.use,Me.walkTokens,Me.parseInline,Le.parse,Se.lex;var Oe={"&":"&","<":"<",">":">",'"':""","'":"'"},Ie={"&":"&","<":"<",">":">",""":'"',"'":"'"},_e=/(&|<|>|"|')/g,Ue=/[&<>"']/g;function qe(e){return Oe[e]}function je(e){return Ie[e]}function De(e){return null==e?"":String(e).replace(Ue,qe)}function Be(e){return null==e?"":String(e).replace(_e,je)}De.options=Be.options={};var Fe={encode:De,escape:De,decode:Be,unescape:Be,version:"1.0.0-browser"};var Ne=function e(t){for(var n,s,i=Array.prototype.slice.call(arguments,1);i.length;)for(s in n=i.shift())n.hasOwnProperty(s)&&("[object Object]"===Object.prototype.toString.call(t[s])?t[s]=e(t[s],n[s]):t[s]=n[s]);return t},We=function(e){return"string"==typeof e?e.toLowerCase():e};function ze(e,t){return e[t]=!0,e}var He=function(e){return e.reduce(ze,{})},Qe={uris:He(["background","base","cite","href","longdesc","src","usemap"])},Ve={voids:He(["area","br","col","hr","img","wbr","input","base","basefont","link","meta"])},Ge=Fe,Ke=We,Ze=Ve,Ye=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,Xe=/^<\s*\/\s*([\w:-]+)[^>]*>/,Je=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,et=/^=0&&(t.comment&&t.comment(e.substring(4,s)),e=e.substring(s+3),n=!1):tt.test(e)?o(Xe,l):et.test(e)&&o(Ye,a);var s;!function(){if(!n)return;var s,i=e.indexOf("<");i>=0?(s=e.substring(0,i),e=e.substring(i)):(s=e,e="");t.chars&&t.chars(s)}()}();var s=e===i;i=e,s&&(e="")}function o(t,s){var i=e.match(t);i&&(e=e.substring(i[0].length),i[0].replace(t,s),n=!1)}function a(e,n,i,r){var o={},a=Ke(n),l=Ze.voids[a]||!!r;i.replace(Je,(function(e,t,n,s,i){o[t]=void 0===n&&void 0===s&&void 0===i?void 0:Ge.decode(n||s||i||"")})),l||s.push(a),t.start&&t.start(a,o,l)}function l(e,n){var i,r=0,o=Ke(n);if(o)for(r=s.length-1;r>=0&&s[r]!==o;r--);if(r>=0){for(i=s.length-1;i>=r;i--)t.end&&t.end(s[i]);s.length=r}}l()},lt=function(e,t){var n,s=t||{};return a(),{start:function(e,t,o){var a=st(e);if(n.ignoring)return void r(a);if(-1===(s.allowedTags||[]).indexOf(a))return void r(a);if(s.filter&&!s.filter({tag:a,attrs:t}))return void r(a);i("<"),i(a),Object.keys(t).forEach((function(e){var n=t[e],r=(s.allowedClasses||{})[a]||[],o=(s.allowedAttributes||{})[a]||[],l=st(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!==it.uris[l]||function(e){var t=e[0];if("#"===t||"/"===t)return!0;var n=e.indexOf(":");if(-1===n)return!0;var i=e.indexOf("?");if(-1!==i&&n>i)return!0;var r=e.indexOf("#");return-1!==r&&n>r||s.allowedSchemes.some(o);function o(t){return 0===e.indexOf(t+":")}}(n)))&&(i(" "),i(e),"string"==typeof n&&(i('="'),i(nt.encode(n)),i('"')))})),i(o?"/>":">")},end:function(e){var t=st(e);-1!==(s.allowedTags||[]).indexOf(t)&&!1===n.ignoring?(i("")):o(t)},chars:function(e){!1===n.ignoring&&i(s.transformText?s.transformText(e):e)}};function i(t){e.push(t)}function r(e){rt.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}}},ct={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 dt(e,t,n){var s=[],i=!0===n?t:ot({},ct,t),r=lt(s,i);return at(e,r),s.join("")}dt.defaults=ct;const ht=b(dt),ut={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","data-src","class","loading"],code:["class"],span:["class","style"]},filter:e=>([["code",/^hljs\W+language-(.*)$/],["span",/^(hljs-.*)$/],["img",/^lazyload$/]].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 pt(e){return ht(e,ut)}var gt={exports:{}};gt.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 s(e){return''+e+""}return function(e,i){void 0===i&&(i={});var r=i.colors;void 0===r&&(r=n);var o=0,a={},l=new RegExp("("+/[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|\w+/.source+"|"+/'+t+"";return o=++o%r.length,l}))}}();const mt=b(gt.exports);function ft(e){return mt(e)}function kt(e){const t=new Me.Renderer;return t.link=yt(t,t.link),t.code=vt(),t.image=$t(t,t.image,e),t}const yt=(e,t)=>(n,s,i)=>{const r=(e=>{try{return new URL(e).origin}catch(t){return""}})(n)===window.location.origin;return t.call(e,n,s,i).replace(/^
    (e,t)=>{const n=t||"plaintext";let s=e;return window.hljs?n&&window.hljs.getLanguage(n)&&(s=window.hljs.highlight(n,e).value):s=ft(e),`
    \n${s.replace(/&/g,"&")}\n
    `},$t=(e,t,{imgLazyLoad:n})=>(s,i,r)=>{const o=t.call(e,s,i,r);return n?"native"===n||!0===n?o.replace(/^${t}`)).replace(/\[(.*?)\]\((.*?)\)/g,((e,t,n)=>`
    ${t}`)).replace(/\n/g,"
    ")}(e));let s=pt(n);return wt.forEach((e=>{"function"==typeof e&&(s=e(s))})),s}function St(...e){const t=e=>e&&"object"==typeof e&&e.constructor===Object;return e.reduce(((e,n)=>(Object.keys(null!=n?n:{}).forEach((s=>{if("__proto__"===s||"constructor"===s||"prototype"===s)return;const i=e[s],r=n[s];Array.isArray(i)&&Array.isArray(r)?e[s]=i.concat(...r):t(i)&&t(r)?e[s]=St(i,r):e[s]=r})),e)),{})}class Tt{constructor(e){g(this,"loading",!1),g(this,"listLastFetch"),g(this,"comments",[]),g(this,"notifies",[]),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)}getNotifies(){return this.notifies}updateNotifies(e){this.notifies=e,this.events.trigger("notifies-updated",this.notifies)}getPage(){return this.page}updatePage(e){this.page=e,this.events.trigger("page-loaded",e)}}function At(e=""){const t=document.createElement("div");return t.innerHTML=e.trim(),t.firstElementChild||t}function Lt(e){const t=document.createElement("div");t.innerText=e;return t.innerHTML}function Pt(e){const t=RegExp(`[?&]${e}=([^&]*)`).exec(window.location.search);return t&&decodeURIComponent(t[1].replace(/\+/g," "))}function Rt(e,t){const n=e=>{const t=e.getBoundingClientRect(),n=window.pageXOffset||document.documentElement.scrollLeft,s=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+s,left:t.left+n}},s=n(e);if(!t)return s;const i=n(t);return{top:s.top-i.top,left:s.left-i.left}}function Mt(e,t){let n=e.toString();for(;n.lengthe)){try{const n=e.getTime(),s=(new Date).getTime()-n,i=Math.floor(s/864e5);if(0===i){const e=s%864e5,n=Math.floor(e/36e5);if(0===n){const n=e%36e5,s=Math.floor(n/6e4);if(0===s){const e=n%6e4,s=Math.round(e/1e3);return s<10?t("now"):`${s} ${t("seconds")}`}return`${s} ${t("minutes")}`}return`${n} ${t("hours")}`}return i<0?t("now"):i<8?`${i} ${t("days")}`:function(e){const t=Mt(e.getDate(),2),n=Mt(e.getMonth()+1,2);return`${Mt(e.getFullYear(),2)}-${n}-${t}`}(e)}catch(n){return console.error(n)," - "}}function It(){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(i){return console.error(i),e}const s=Number(n.platformVersion.split(".")[0]);return"Windows"===t.platform&&s>=13?e.replace(/Windows NT 10.0/,"Windows NT 11.0"):"macOS"===t.platform&&s>=11?e.replace(/(Mac OS X \d+_\d+_\d+|Mac OS X)/,`Mac OS X ${n.platformVersion.replace(/\./g,"_")}`):e}))}function _t(e){let t;try{t=new URL(e)}catch(n){return!1}return"http:"===t.protocol||"https:"===t.protocol}function Ut(e){return t=e.base,n=e.path,`${t.replace(/\/$/,"")}/${n.replace(/^\//,"")}`;var t,n}const qt={placeholder:"Leave a comment",noComment:"No Comment",send:"Send",signIn:"Sign in",signUp:"Sign up",save:"Save",nick:"Nickname",email:"Email",link:"Website",emoticon:"Emoji",preview:"Preview",uploadImage:"Upload 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:"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",noAccountPrompt:"Don't have an account?",haveAccountPrompt:"Already have an account?",forgetPassword:"Forget Password",resetPassword:"Reset Password",verificationCode:"Verification Code",verifySend:"Verify",verifyResend:"Resend",waitSeconds:"Wait {seconds}s",emailVerified:"Email has been verified",password:"Password",username:"Username",nextStep:"Next Step",skipNotVerify:"Skip, do not verify",logoutConfirm:"Are you sure to logout?",accountMergeNotice:"Your email has multiple accounts with different id.",accountMergeSelectOne:"Please select one you want to merge all the data into it.",accountMergeConfirm:"All data will be merged into one account, the id is {id}.",dismiss:"Dismiss",merge:"Merge",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 best experience!",currentVersion:"Current Version",ignore:"Ignore",open:"Open",openName:"Open {name}"},jt="ArtalkI18n",Dt={en:qt,"en-US":qt,"zh-CN":{placeholder:"键入内容...",noComment:"「此时无声胜有声」",send:"发送",signIn:"登录",signUp:"注册",save:"保存",nick:"昵称",email:"邮箱",link:"网址",emoticon:"表情",preview:"预览",uploadImage:"上传图片",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:"控制中心",noAccountPrompt:"没有账号?",haveAccountPrompt:"已有账号?",forgetPassword:"忘记密码",resetPassword:"重置密码",verificationCode:"验证码",verifySend:"发送验证码",verifyResend:"重新发送",waitSeconds:"等待 {seconds}秒",emailVerified:"邮箱已验证",password:"密码",username:"用户名",nextStep:"下一步",skipNotVerify:"跳过,不验证",logoutConfirm:"确定要退出登录吗?",accountMergeNotice:"您的电子邮件下有多个不同 ID 的账户。",accountMergeSelectOne:"请选择将所有数据合并到其中的一个。",accountMergeConfirm:"所有数据将合并到 ID 为 {id} 的账户中。",dismiss:"忽略",merge:"合并",frontend:"前端",backend:"后端",loading:"加载中",loadFail:"加载失败",editing:"修改中",editFail:"修改失败",deleting:"删除中",deleteFail:"删除失败",reqGot:"请求响应",reqAborted:"请求超时或意外终止",updateMsg:"请更新 Artalk {name} 以获得更好的体验!",currentVersion:"当前版本",ignore:"忽略",open:"打开",openName:"打开{name}"}};function Bt(e){return e=e.replace(/^([a-zA-Z]+)(-[a-zA-Z]+)?$/,((e,t,n)=>t.toLowerCase()+(n||"").toUpperCase())),Dt[e]?Dt[e]:window[jt]&&window[jt][e]?window[jt][e]:Dt.en}let Ft="en",Nt=Bt(Ft);function Wt(e){e!==Ft&&(Ft=e,Nt="string"==typeof e?Bt(e):e)}function zt(e,t={}){let n=(null==Nt?void 0:Nt[e])||e;return n=n.replace(/\{\s*(\w+?)\s*\}/g,((e,n)=>t[n]||"")),Lt(n)}class Ht{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 Qt={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:".artalk-comment-count",pvEl:".artalk-pv-count",statPageKeyAttr:"data-page-key",gravatar:{mirror:"https://www.gravatar.com/avatar/",params:"sha256=1&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:"en"};function Vt(e,t=!1){const n=t?St(Qt,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(s){throw console.error(s),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 Gt(e,t){return{baseURL:`${e.server}/api/v2`,siteName:e.site||"",pageKey:e.pageKey||"",pageTitle:e.pageTitle||"",timeout:e.reqTimeout,getApiToken:()=>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,handlers:null==t?void 0:t.getApiHandlers()}}function Kt(e,t,n){let s=null;const i=()=>{const i=(()=>{const n=e.getConf(),s={};return t.forEach((e=>{s[e]=n[e]})),s})();var r,o;(null==s||(r=s,o=i,!(JSON.stringify(r)===JSON.stringify(o))))&&(s=i,n(i))};e.on("mounted",i),e.on("updated",i)}class Zt{constructor(e){g(this,"conf"),g(this,"data"),g(this,"$root"),g(this,"events",new Ht),g(this,"mounted",!1),g(this,"apiHandlers",null),g(this,"getCommentList",this.getCommentNodes),g(this,"getCommentDataList",this.getComments),this.conf=e,this.$root=e.el,this.$root.classList.add("artalk"),this.$root.innerHTML="",this.data=new Tt(this.events),this.on("mounted",(()=>{this.mounted=!0}))}inject(e,t){this[e]=t}get(e){return this[e]}getApi(){return new C(Gt(this.conf,this))}getApiHandlers(){return this.apiHandlers||(this.apiHandlers=function(e){const t=function(){const e=[];return{add:(t,n)=>{e.push({action:t,handler:n})},get:()=>e}}();return t.add("need_captcha",(t=>e.checkCaptcha(t))),t.add("need_login",(()=>e.checkAdmin({}))),t}(this)),this.apiHandlers}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")}getCommentNodes(){return this.list.getCommentNodes()}getComments(){return this.data.getComments()}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){return this.checkerLauncher.checkAdmin(e)}checkCaptcha(e){return 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 zt(e,t)}setDarkMode(e){this.updateConf({darkMode:e})}updateConf(e){this.conf=St(this.conf,Vt(e,!1)),this.mounted&&this.events.trigger("updated",this.conf)}getConf(){return this.conf}getEl(){return this.$root}getMarked(){return Ct()}watchConf(e,t){Kt(this,e,t)}}function Yt(e,t){let n=e.querySelector(":scope > .atk-loading");n||(n=At(''),(null==t?void 0:t.transparentBg)&&(n.style.background="transparent"),e.appendChild(n)),n.style.display="";const s=n.querySelector(".atk-loading-spinner");s&&(s.style.display="none",window.setTimeout((()=>{s.isConnected&&(s.style.display="")}),500))}function Xt(e){const t=e.querySelector(":scope > .atk-loading");t&&(t.style.display="none")}function Jt(e,t){e?Yt(t):Xt(t)}function en(e,t=!0,n){let s;if(n){const t=n.getBoundingClientRect();s=e.getBoundingClientRect().top-t.top+n.scrollTop-n.clientHeight/2+e.clientHeight/2}else{const t=e.getBoundingClientRect();s=t.top+window.scrollY-(window.innerHeight/2-t.height/2)}const i={top:s,left:0,behavior:"instant"};n?n.scroll(i):window.scroll(i)}function tn(e,t){!function(e,t,n="in"){e.classList.add(`atk-fade-${n}`);const s=()=>{e.classList.remove(`atk-fade-${n}`),e.removeEventListener("animationend",s)};e.addEventListener("animationend",s)}(e,0,"in")}function nn(e,t,n='Artalk Error'){let s=e.querySelector(".atk-error-layer");if(null===t)return void(null!==s&&s.remove());s||(s=At(`
    ${n}
    `),e.appendChild(s));const i=s.querySelector(".atk-error-text");i.innerHTML="",null!==t&&(t instanceof HTMLElement?i.appendChild(t):i.innerText=t)}function sn(e){const t=At('
    '),n=At('');n.style.display="none",Yt(t,{transparentBg:!0}),n.src=e.getOpts().getCaptchaIframeURL(),n.onload=()=>{n.style.display="",Xt(t)},t.append(n);const s=At('
    ');t.append(s),e.hideInteractInput();let i=!1;return function t(){return k(this,null,(function*(){var n;if(yield(n=1e3,new Promise((e=>{window.setTimeout((()=>{e(null)}),n)}))),i)return;let s=!1;try{s=(yield e.getApi().captcha.getCaptchaStatus()).data.is_pass}catch(r){s=!1}s?e.triggerSuccess():t()}))}(),s.onclick=()=>{i=!0,e.cancel()},t}const rn={request:(e,t)=>e.getApi().captcha.verifyCaptcha({value:t}),body:e=>e.get("iframe")?sn(e):function(e){const t=At(`${zt("captchaCheck")}`);return t.querySelector(".atk-captcha-img").onclick=()=>{const n=t.querySelector(".atk-captcha-img");e.getApi().captcha.getCaptcha().then((e=>{n.setAttribute("src",e.data.img_data)})).catch((e=>{console.error("Failed to get captcha image ",e)}))},t}(e),onSuccess(e,t,n,s){e.set("val",n)},onError(e,t,n,s){s.querySelector(".atk-captcha-img").click(),s.querySelector('input[type="text"]').value=""}},on={inputType:"password",request(e,t){return k(this,null,(function*(){return(yield e.getApi().user.login({name:e.getUser().getData().nick,email:e.getUser().getData().email,password:t})).data}))},body:e=>At(`${zt("adminCheck")}`),onSuccess(e,t,n,s){e.getUser().update({isAdmin:!0,token:t.token}),e.getOpts().onReload()},onError(e,t,n,s){}};class an{constructor(e){g(this,"$el"),g(this,"$content"),g(this,"$actions"),this.$el=At('
    \n
    \n
    \n
    \n
    \n
    '),this.$actions=this.$el.querySelector(".atk-layer-dialog-actions"),this.$content=this.$el.querySelector(".atk-layer-dialog-content"),this.$content.appendChild(e)}setYes(e){const t=At(``);return t.onclick=this.onBtnClick(e),this.$actions.appendChild(t),this}setNo(e){const t=At(``);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 ln(e){return t=>new Promise(((n,s)=>{const i=t.onCancel;t.onCancel=()=>{i&&i(),s(new Error("user canceled the checker"))};const r=t.onSuccess;t.onSuccess=()=>{r&&r(),n()},e(t)}))}class cn{constructor(e){g(this,"checkCaptcha",ln((e=>{this.fire(rn,e,(t=>{t.set("img_data",e.img_data),t.set("iframe",e.iframe)}))}))),g(this,"checkAdmin",ln((e=>{this.fire(on,e)}))),this.opts=e}fire(e,t,n){const s=this.opts.getCtx().get("layerManager").create(`checker-${(new Date).getTime()}`);s.show();const i=()=>{s.destroy()},r={};let o=!1;const a={set:(e,t)=>{r[e]=t},get:e=>r[e],getOpts:()=>this.opts,getUser:()=>this.opts.getCtx().get("user"),getApi:()=>this.opts.getApi(),hideInteractInput:()=>{o=!0},triggerSuccess:()=>{i(),e.onSuccess&&e.onSuccess(a,"","",l),t.onSuccess&&t.onSuccess()},cancel:()=>{i(),t.onCancel&&t.onCancel()}};n&&n(a);const l=At();l.appendChild(e.body(a));const c=At(``);let d;l.appendChild(c),setTimeout((()=>c.focus()),80),c.onkeyup=e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),s.getEl().querySelector('button[data-action="confirm"]').click())};const h=new an(l);h.setYes((n=>{const s=c.value.trim();d||(d=n.innerText);const r=()=>{n.innerText=d||"",n.classList.remove("error")};return n.innerText=`${zt("loading")}...`,e.request(a,s).then((n=>{i(),e.onSuccess&&e.onSuccess(a,n,s,l),t.onSuccess&&t.onSuccess()})).catch((t=>{var i;i=String(t.message||String(t)),n.innerText=i,n.classList.add("error"),e.onError&&e.onError(a,t,s,l);const o=setTimeout((()=>r()),3e3);c.onfocus=()=>{r(),clearTimeout(o)}})),!1})),h.setNo((()=>(i(),t.onCancel&&t.onCancel(),!1))),o&&(c.style.display="none",h.$el.querySelector(".atk-layer-dialog-actions").style.display="none"),s.getEl().append(h.$el),t.onMount&&t.onMount(h.$el)}}class dn{constructor(e){g(this,"$el"),this.ctx=e}get conf(){return this.ctx.conf}getEl(){return this.$el}}const hn={$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",$bottomLeft:".atk-bottom-left",$stateWrap:".atk-state-wrap",$plugBtnWrap:".atk-plug-btn-wrap",$plugPanelWrap:".atk-plug-panel-wrap"};class un{constructor(e){this.kit=e}useBtn(e="
    "){return this.$btn=At(`${e}`),this.$btn}usePanel(e="
    "){return this.$panel=At(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 pn extends un{constructor(){super(...arguments),g(this,"isMoved",!1)}move(e){if(this.isMoved)return;this.isMoved=!0;const t=this.kit.useUI().$el;t.after(At('
    '));const n=At("
    ");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 gn{constructor(e){g(this,"stateCurt","normal"),g(this,"stateUnmountFn",null),this.editor=e}get(){return this.stateCurt}switch(e,t){var n,s,i,r,o;if(this.stateUnmountFn&&(this.stateUnmountFn(),this.stateUnmountFn=null,null==(s=null==(n=this.editor.getPlugs())?void 0:n.get(pn))||s.back()),"normal"!==e&&t){let n=t.$comment;this.editor.conf.flatMode||(n=n.querySelector(".atk-footer")),null==(r=null==(i=this.editor.getPlugs())?void 0:i.get(pn))||r.move(n);const s=this.editor.ctx.conf.scrollRelativeTo&&this.editor.ctx.conf.scrollRelativeTo();en(this.editor.getUI().$el,!0,s);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 mn extends dn{constructor(e){super(e),g(this,"ui"),g(this,"state"),this.ui=function(){const e=At('
    \n
    \n \n \n \n
    \n
    \n \n
    \n \n
    \n
    \n \n \n
    \n
    \n \n
    \n
    \n
    \n
    \n'),t={$el:e};return Object.entries(hn).forEach((([n,s])=>{t[n]=e.querySelector(s)})),t}(),this.$el=this.ui.$el,this.state=new gn(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 Et(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,s=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=s}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 s=At(`
    `);s.querySelector(".atk-notify-content").innerHTML=Lt(t).replace("\n","
    "),e.appendChild(s);const i=()=>{s.classList.add("atk-fade-out"),setTimeout((()=>{s.remove()}),200)};let r;r=window.setTimeout((()=>{i()}),3e3),s.addEventListener("click",(()=>{i(),window.clearTimeout(r)}))}(this.ui.$notifyWrap,e,t)}showLoading(){Yt(this.ui.$el)}hideLoading(){Xt(this.ui.$el)}submit(){const e=()=>this.ctx.trigger("editor-submit");this.ctx.conf.beforeSubmit?this.ctx.conf.beforeSubmit(this,e):e()}}class fn extends dn{constructor(e){super(e),g(this,"layer"),g(this,"$header"),g(this,"$closeBtn"),g(this,"$iframeWrap"),g(this,"$iframe"),g(this,"refreshOnShow",!0),g(this,"animTimer"),this.$el=At('
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n'),this.$header=this.$el.querySelector(".atk-sidebar-header"),this.$closeBtn=this.$header.querySelector(".atk-sidebar-close"),this.$iframeWrap=this.$el.querySelector(".atk-sidebar-iframe-wrap"),this.$closeBtn.onclick=()=>{this.hide()},this.ctx.on("user-changed",(()=>{this.refreshOnShow=!0}))}show(){return k(this,arguments,(function*(e={}){if(this.$el.style.transform="",this.initLayer(),this.layer.show(),this.refreshOnShow)this.refreshOnShow=!1,this.$iframeWrap.innerHTML="",this.$iframe=this.createIframe(e.view),this.$iframeWrap.append(this.$iframe);else{const e=this.$iframe,t=e.src;this.getDarkMode()!==t.includes("&darkMode=1")&&this.iframeLoad(e,this.getDarkMode()?t.concat("&darkMode=1"):t.replace("&darkMode=1",""))}this.authCheck({onSuccess:()=>this.show(e)}),this.animTimer=setTimeout((()=>{this.animTimer=void 0,this.$el.style.transform="translate(0, 0)",setTimeout((()=>{this.ctx.getData().updateNotifies([])}),0),this.ctx.trigger("sidebar-show")}),100)}))}hide(){var e;null==(e=this.layer)||e.hide()}authCheck(e){return k(this,null,(function*(){const t=(yield this.ctx.getApi().user.getUserStatus(u({},this.ctx.getApi().getUserFields()))).data;t.is_admin&&!t.is_login&&(this.refreshOnShow=!0,this.ctx.checkAdmin({onSuccess:()=>{setTimeout((()=>{e.onSuccess()}),500)},onCancel:()=>{this.hide()}}),this.hide())}))}initLayer(){this.layer||(this.layer=this.ctx.get("layerManager").create("sidebar",this.$el),this.layer.setOnAfterHide((()=>{this.ctx.editorResetState(),this.animTimer&&clearTimeout(this.animTimer),this.$el.style.transform="",this.ctx.trigger("sidebar-hide")})))}createIframe(e){const t=At(''),n=Ut({base:this.ctx.conf.server,path:"/sidebar/"}),s={pageKey:this.conf.pageKey,site:this.conf.site||"",user:JSON.stringify(this.ctx.get("user").getData()),time:+new Date};e&&(s.view=e),this.getDarkMode()&&(s.darkMode="1");const i=new URLSearchParams(s);return this.iframeLoad(t,`${n}?${i.toString()}`),t}getDarkMode(){return"auto"===this.conf.darkMode?window.matchMedia("(prefers-color-scheme: dark)").matches:this.conf.darkMode}iframeLoad(e,t){e.src=t,Yt(this.$iframeWrap),e.onload=()=>{Xt(this.$iframeWrap)}}}const kn=e=>({import:t=>{(function(e,t="DATE_DESC",n=2){const s=[];e.filter((e=>0===e.rid)).forEach((t=>{const i={id:t.id,comment:t,children:[],level:1};i.parent=i,s.push(i),function t(s){const i=e.filter((e=>e.rid===s.id));0!==i.length&&(s.level>=n&&(s=s.parent),i.forEach((e=>{const n={id:e.id,comment:e,children:[],parent:s,level:s.level+1};s.children.push(n),t(n)})))}(i)}));const i=(n,s)=>{let i=n.id-s.id;return"DATE_ASC"===t?i=+new Date(n.comment.date)-+new Date(s.comment.date):"DATE_DESC"===t?i=+new Date(s.comment.date)-+new Date(n.comment.date):"SRC_INDEX"===t?i=e.indexOf(n.comment)-e.indexOf(s.comment):"VOTE_UP_DESC"===t&&(i=s.comment.vote_up-n.comment.vote_up),i};return function e(t){t.forEach((t=>{t.children=t.children.sort(i),e(t.children)}))}(s),s})(t,e.nestSortBy,e.nestMax).forEach((n=>{var s;const i=e.createCommentNode(n.comment);null==(s=e.$commentsWrap)||s.appendChild(i.getEl()),i.getRender().playFadeAnim();const r=(n,s)=>{s.children.forEach((s=>{const i=t.find((e=>e.id===s.comment.rid)),o=s.comment,a=e.createCommentNode(o,i);n.putChild(a),r(a,s)}))};r(i,n),i.getRender().checkHeightLimit()}))},insert:(t,n)=>{var s;const i=e.createCommentNode(t,n);if(0===t.rid)null==(s=e.$commentsWrap)||s.prepend(i.getEl());else{const n=e.findCommentNode(t.rid);n&&(n.putChild(i,"DATE_ASC"===e.nestSortBy?"append":"prepend"),i.getParents().forEach((e=>{e.getRender().heightLimitRemoveForChildren()})))}i.getRender().checkHeightLimit(),i.scrollIntoView(),i.getRender().playFadeAnim()}});function yn(e,t,n,s){n.is_collapsed&&(n.is_allow_reply=!1);const i=e.createCommentNode(n,s);if(n.visible){const n=i.getEl(),s=e.$commentsWrap;"append"===t&&(null==s||s.append(n)),"prepend"===t&&(null==s||s.prepend(n)),i.getRender().playFadeAnim()}return i.getRender().checkHeightLimit(),i}class vn{constructor(e){this.options=e}getStrategy(){return this.options.flatMode?(e=this.options,{import:t=>{t.forEach((n=>{const s=0===n.rid?void 0:t.find((e=>e.id===n.rid));yn(e,"append",n,s)}))},insert:(t,n)=>{yn(e,"prepend",t,n).scrollIntoView()}}):kn(this.options);var e}import(e){this.getStrategy().import(e)}insert(e,t){this.getStrategy().insert(e,t)}}function $n(e,t){t.forEach((({el:t,max:n,imgCheck:s})=>{if(!t)return;s&&(t.style.maxHeight=`${n+1}px`);let i=!1;const r=()=>{if(i)return;if(function(e){return parseFloat(getComputedStyle(e,null).height.replace("px",""))||0}(t)<=n)return;e.scrollable?function(e){if(!e.el)return;if(e.el.classList.contains(xn))return;e.el.classList.add(xn),e.el.style.height=`${e.max}px`}({el:t,max:n}):function(e){if(!e.el)return;if(!e.max)return;if(e.el.classList.contains(bn))return;e.el.classList.add(bn),e.el.style.height=`${e.max}px`,e.el.style.overflow="hidden";const t=At(`
    ${zt("readMore")}`);t.onclick=t=>{t.stopPropagation(),wn(e.el),e.afterExpandBtnClick&&e.afterExpandBtnClick(t)},e.el.append(t)}({el:t,max:n,afterExpandBtnClick:()=>{var t;i=!0,null==(t=e.afterExpandBtnClick)||t.call(e)}})};if(r(),s){const e=t.querySelectorAll(".atk-content img");0===e.length&&(t.style.maxHeight=""),e.forEach((e=>{e.onload=()=>r()}))}}))}const bn="atk-height-limit";function wn(e){e&&e.classList.contains(bn)&&(e.classList.remove(bn),Array.from(e.children).forEach((e=>{e.classList.contains("atk-height-limit-btn")&&e.remove()})),e.style.height="",e.style.maxHeight="",e.style.overflow="")}const xn="atk-height-limit-scroll";function Cn(e){if(e.$headerNick=e.$el.querySelector(".atk-nick"),e.data.link){const t=At('');t.innerText=e.data.nick,t.href=_t(e.data.link)?e.data.link:`https://${e.data.link}`,e.$headerNick.append(t)}else e.$headerNick.innerText=e.data.nick}function En(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 s=At('');s.innerText=t.replace("管理员",zt("admin")),s.style.backgroundColor=n||"",e.$headerBadgeWrap.append(s)}else if(e.data.is_verified){const t=At(``);e.$headerBadgeWrap.append(t)}if(e.data.is_pinned){const t=At(`${zt("pin")}`);e.$headerBadgeWrap.append(t)}}function Sn(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 Tn(e){if(!e.opts.uaBadge&&!e.data.ip_region)return;let t=e.$header.querySelector("atk-ua-wrap");if(t||(t=At(''),e.$header.append(t)),t.innerHTML="",e.data.ip_region){const n=At('');n.innerText=e.data.ip_region,t.append(n)}if(e.opts.uaBadge){const{browser:n,os:s}=e.comment.getUserUA();if(String(n).trim()){const e=At('');e.innerText=n,t.append(e)}if(String(s).trim()){const e=At('');e.innerText=s,t.append(e)}}}class An{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=At(''),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||zt("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||`${zt("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,s){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),s&&s()}),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 Ln(e){e.opts.vote&&(e.voteBtnUp=new An((()=>`${zt("voteUp")} (${e.data.vote_up||0})`)).appendTo(e.$actions),e.voteBtnUp.setClick((()=>{e.comment.getActions().vote("up")})),e.opts.voteDown&&(e.voteBtnDown=new An((()=>`${zt("voteDown")} (${e.data.vote_down||0})`)).appendTo(e.$actions),e.voteBtnDown.setClick((()=>{e.comment.getActions().vote("down")}))))}function Pn(e){if(!e.data.is_allow_reply)return;const t=At(`${zt("reply")}`);e.$actions.append(t),t.addEventListener("click",(t=>{t.stopPropagation(),e.opts.replyComment(e.data,e.$el)}))}function Rn(e){const t=new An({text:()=>e.data.is_collapsed?zt("expand"):zt("collapse"),adminOnly:!0});t.appendTo(e.$actions),t.setClick((()=>{e.comment.getActions().adminEdit("collapsed",t)}))}function Mn(e){const t=new An({text:()=>e.data.is_pending?zt("pending"):zt("approved"),adminOnly:!0});t.appendTo(e.$actions),t.setClick((()=>{e.comment.getActions().adminEdit("pending",t)}))}function On(e){const t=new An({text:()=>e.data.is_pinned?zt("unpin"):zt("pin"),adminOnly:!0});t.appendTo(e.$actions),t.setClick((()=>{e.comment.getActions().adminEdit("pinned",t)}))}function In(e){const t=new An({text:zt("edit"),adminOnly:!0});t.appendTo(e.$actions),t.setClick((()=>{e.opts.editComment(e.data,e.$el)}))}function _n(e){const t=new An({text:zt("delete"),confirm:!0,confirmText:zt("deleteConfirm"),adminOnly:!0});t.appendTo(e.$actions),t.setClick((()=>{e.comment.getActions().adminDelete(t)}))}const Un={Avatar:function(e){const t=e.$el.querySelector(".atk-avatar"),n=At(""),s=e.opts.avatarURLBuilder;if(n.src=s?s(e.data):e.comment.getGravatarURL(),e.data.link){const s=At('');s.href=_t(e.data.link)?e.data.link:`https://${e.data.link}`,s.append(n),t.append(s)}else t.append(n)},Header:function(e){Object.entries({renderNick:Cn,renderVerifyBadge:En,renderDate:Sn,renderUABadge:Tn}).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=At(`\n
    \n ${zt("collapsedMsg")}\n ${zt("expand")}\n
    `);e.$body.insertAdjacentElement("beforeend",t);const n=t.querySelector(".atk-show-btn");n.addEventListener("click",(t=>{t.stopPropagation(),e.$content.classList.contains("atk-hide")?(e.$content.innerHTML=e.comment.getContentMarked(),e.$content.classList.remove("atk-hide"),tn(e.$content),n.innerText=zt("collapse")):(e.$content.innerHTML="",e.$content.classList.add("atk-hide"),n.innerText=zt("expand"))}))},ReplyAt:function(e){e.opts.flatMode||0===e.data.rid||e.opts.replyTo&&(e.$replyAt=At(''),e.$replyAt.querySelector(".atk-nick").innerText=`${e.opts.replyTo.nick}`,e.$replyAt.onclick=()=>{e.comment.getActions().goToReplyComment()},e.$headerBadgeWrap.insertAdjacentElement("afterend",e.$replyAt))},ReplyTo:function(e){if(!e.opts.flatMode)return;if(!e.opts.replyTo)return;e.$replyTo=At(`\n
    \n
    ${zt("reply")} :
    \n
    \n
    `);const t=e.$replyTo.querySelector(".atk-nick");t.innerText=`@${e.opts.replyTo.nick}`,t.onclick=()=>{e.comment.getActions().goToReplyComment()};let n=Et(e.opts.replyTo.content);e.opts.replyTo.is_collapsed&&(n=`[${zt("collapsed")}]`),e.$replyTo.querySelector(".atk-content").innerHTML=n,e.$body.prepend(e.$replyTo)},Pending:function(e){if(!e.data.is_pending)return;const t=At(`
    ${zt("pendingMsg")}
    `);e.$body.prepend(t)},Actions:function(e){Object.entries({renderVote:Ln,renderReply:Pn,renderCollapse:Rn,renderModerator:Mn,renderPin:On,renderEdit:In,renderDel:_n}).forEach((([t,n])=>{n(e)}))}};class qn{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 data(){return this.comment.getData()}get opts(){return this.comment.getOpts()}render(){var e;return this.$el=At('
    \n
    \n
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n'),this.$main=this.$el.querySelector(".atk-main"),this.$header=this.$el.querySelector(".atk-header"),this.$body=this.$el.querySelector(".atk-body"),this.$content=this.$body.querySelector(".atk-content"),this.$actions=this.$el.querySelector(".atk-actions"),this.$el.setAttribute("id",`atk-comment-${this.data.id}`),e=this,Object.entries(Un).forEach((([t,n])=>{n(e)})),this.$childrenWrap&&this.$main.append(this.$childrenWrap),this.$el}checkHeightLimit(){const e=this.opts.heightLimit;if(!e||!e.content||!e.children)return;const t=e.content,n=e.children;$n({afterExpandBtnClick:()=>{const e=this.comment.getChildren();1===e.length&&wn(e[0].getRender().$content)},scrollable:e.scrollable},[{el:this.$content,max:t,imgCheck:!0},{el:this.$replyTo,max:t,imgCheck:!0},{el:this.$childrenWrap,max:n,imgCheck:!1}])}heightLimitRemoveForChildren(){this.$childrenWrap&&wn(this.$childrenWrap)}playFadeAnim(){tn(this.comment.getRender().$el)}playFadeAnimForBody(){tn(this.comment.getRender().$body)}playFlashAnim(){this.$el.classList.remove("atk-flash-once"),window.setTimeout((()=>{this.$el.classList.add("atk-flash-once")}),150)}getChildrenWrap(){return this.$childrenWrap||(this.$childrenWrap=At('
    '),this.$main.append(this.$childrenWrap)),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.stopPropagation(),window.open(e)}}setOpenAction(e){this.setOpenable(!0),this.$el.onclick=t=>{t.stopPropagation(),e()}}}class jn{constructor(e){g(this,"comment"),this.comment=e}get data(){return this.comment.getData()}get opts(){return this.comment.getOpts()}getApi(){return this.comment.getOpts().getApi()}vote(e){const t="up"===e?this.comment.getRender().voteBtnUp:this.comment.getRender().voteBtnDown;this.getApi().votes.vote(`comment_${e}`,this.data.id,u({},this.getApi().getUserFields())).then((e=>{var t,n;this.data.vote_up=e.data.up,this.data.vote_down=e.data.down,null==(t=this.comment.getRender().voteBtnUp)||t.updateText(),null==(n=this.comment.getRender().voteBtnDown)||n.updateText()})).catch((e=>{null==t||t.setError(zt("voteFail")),console.error(e)}))}adminEdit(e,t){if(t.isLoading)return;t.setLoading(!0,`${zt("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.getApi().comments.updateComment(this.data.id,u({},n)).then((e=>{t.setLoading(!1),this.comment.setData(e.data)})).catch((e=>{console.error(e),t.setError(zt("editFail"))}))}adminDelete(e){e.isLoading||(e.setLoading(!0,`${zt("deleting")}...`),this.getApi().comments.deleteComment(this.data.id).then((()=>{e.setLoading(!1),this.opts.onDelete&&this.opts.onDelete(this.comment)})).catch((t=>{console.error(t),e.setError(zt("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 Dn{constructor(e,t){g(this,"$el"),g(this,"renderInstance"),g(this,"actionInstance"),g(this,"data"),g(this,"opts"),g(this,"parent"),g(this,"children",[]),g(this,"nestCurt"),this.opts=t,this.data=u({},e),this.data.date=this.data.date.replace(/-/g,"/"),this.parent=null,this.nestCurt=1,this.actionInstance=new jn(this),this.renderInstance=new qn(this)}render(){const e=this.renderInstance.render();this.$el&&this.$el.replaceWith(e),this.$el=e,this.opts.onAfterRender&&this.opts.onAfterRender()}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.getChildrenWrapEl(),s=e.getEl();"append"===t?n.append(s):"prepend"===t&&n.prepend(s),e.getRender().playFadeAnim(),e.getRender().checkHeightLimit()}getChildrenWrapEl(){return this.nestCurt>=this.opts.nestMax?this.parent.getChildrenWrapEl():this.getRender().getChildrenWrap()}getParents(){const e=[];let t=this.parent;for(;t;)e.push(t),t=t.getParent();return e}getEl(){if(!this.$el)throw new Error("comment element not initialized before `getEl()`");return this.$el}focus(){if(!this.$el)throw new Error("comment element not initialized before `focus()`");this.getParents().forEach((e=>{e.getRender().heightLimitRemoveForChildren()})),this.scrollIntoView(),this.getRender().playFlashAnim()}scrollIntoView(){this.$el&&en(this.$el,!1,this.opts.scrollRelativeTo&&this.opts.scrollRelativeTo())}remove(){var e;null==(e=this.$el)||e.remove()}getGravatarURL(){return`${(e={mirror:this.opts.gravatar.mirror,params:this.opts.gravatar.params,emailHash:this.data.email_encrypted}).mirror.replace(/\/$/,"")}/${e.emailHash}?${e.params.replace(/^\?/,"")}`;var e}getContentMarked(){return Et(this.data.content)}getDateFormatted(){return Ot(new Date(this.data.date),zt)}getUserUA(){const e=function(e){const t=window||{},n=navigator||{},s=String(e||n.userAgent),i={os:"",osVersion:"",engine:"",browser:"",device:"",language:"",version:""},r={Trident:s.includes("Trident")||s.includes("NET CLR"),Presto:s.includes("Presto"),WebKit:s.includes("AppleWebKit"),Gecko:s.includes("Gecko/")},o={Safari:s.includes("Safari"),Chrome:s.includes("Chrome")||s.includes("CriOS"),IE:s.includes("MSIE")||s.includes("Trident"),Edge:s.includes("Edge")||s.includes("Edg"),Firefox:s.includes("Firefox")||s.includes("FxiOS"),"Firefox Focus":s.includes("Focus"),Chromium:s.includes("Chromium"),Opera:s.includes("Opera")||s.includes("OPR"),Vivaldi:s.includes("Vivaldi"),Yandex:s.includes("YaBrowser"),Kindle:s.includes("Kindle")||s.includes("Silk/"),360:s.includes("360EE")||s.includes("360SE"),UC:s.includes("UC")||s.includes(" UBrowser"),QQBrowser:s.includes("QQBrowser"),QQ:s.includes("QQ/"),Baidu:s.includes("Baidu")||s.includes("BIDUBrowser"),Maxthon:s.includes("Maxthon"),Sogou:s.includes("MetaSr")||s.includes("Sogou"),LBBROWSER:s.includes("LBBROWSER"),"2345Explorer":s.includes("2345Explorer"),TheWorld:s.includes("TheWorld"),MIUI:s.includes("MiuiBrowser"),Quark:s.includes("Quark"),Qiyu:s.includes("Qiyu"),Wechat:s.includes("MicroMessenger"),Taobao:s.includes("AliApp(TB"),Alipay:s.includes("AliApp(AP"),Weibo:s.includes("Weibo"),Douban:s.includes("com.douban.frodo"),Suning:s.includes("SNEBUY-APP"),iQiYi:s.includes("IqiyiApp")},a={Windows:s.includes("Windows"),Linux:s.includes("Linux")||s.includes("X11"),macOS:s.includes("Macintosh"),Android:s.includes("Android")||s.includes("Adr"),Ubuntu:s.includes("Ubuntu"),FreeBSD:s.includes("FreeBSD"),Debian:s.includes("Debian"),"Windows Phone":s.includes("IEMobile")||s.includes("Windows Phone"),BlackBerry:s.includes("BlackBerry")||s.includes("RIM"),MeeGo:s.includes("MeeGo"),Symbian:s.includes("Symbian"),iOS:s.includes("like Mac OS X"),"Chrome OS":s.includes("CrOS"),WebOS:s.includes("hpwOS")},l={Mobile:s.includes("Mobi")||s.includes("iPh")||s.includes("480"),Tablet:s.includes("Tablet")||s.includes("Pad")||s.includes("Nexus 7")};l.Mobile?l.Mobile=!s.includes("iPad"):o.Chrome&&s.includes("Edg")?(o.Chrome=!1,o.Edge=!0):t.showModalDialog&&t.chrome&&(o.Chrome=!1,o[360]=!0),i.device="PC",i.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&&(i[e]=t)}))}));const d={Windows:()=>{const e=s.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:()=>s.replace(/^.*Android ([\d.]+);.*$/,"$1"),iOS:()=>s.replace(/^.*OS ([\d_]+) like.*$/,"$1").replace(/_/g,"."),Debian:()=>s.replace(/^.*Debian\/([\d.]+).*$/,"$1"),"Windows Phone":()=>s.replace(/^.*Windows Phone( OS)? ([\d.]+);.*$/,"$2"),macOS:()=>s.replace(/^.*Mac OS X ([\d_]+).*$/,"$1").replace(/_/g,"."),WebOS:()=>s.replace(/^.*hpwOS\/([\d.]+);.*$/,"$1")};i.osVersion="",d[i.os]&&(i.osVersion=d[i.os](),i.osVersion===s&&(i.osVersion=""));const h={Safari:()=>s.replace(/^.*Version\/([\d.]+).*$/,"$1"),Chrome:()=>s.replace(/^.*Chrome\/([\d.]+).*$/,"$1").replace(/^.*CriOS\/([\d.]+).*$/,"$1"),IE:()=>s.replace(/^.*MSIE ([\d.]+).*$/,"$1").replace(/^.*rv:([\d.]+).*$/,"$1"),Edge:()=>s.replace(/^.*(Edge|Edg|Edg[A-Z]{1})\/([\d.]+).*$/,"$2"),Firefox:()=>s.replace(/^.*Firefox\/([\d.]+).*$/,"$1").replace(/^.*FxiOS\/([\d.]+).*$/,"$1"),"Firefox Focus":()=>s.replace(/^.*Focus\/([\d.]+).*$/,"$1"),Chromium:()=>s.replace(/^.*Chromium\/([\d.]+).*$/,"$1"),Opera:()=>s.replace(/^.*Opera\/([\d.]+).*$/,"$1").replace(/^.*OPR\/([\d.]+).*$/,"$1"),Vivaldi:()=>s.replace(/^.*Vivaldi\/([\d.]+).*$/,"$1"),Yandex:()=>s.replace(/^.*YaBrowser\/([\d.]+).*$/,"$1"),Kindle:()=>s.replace(/^.*Version\/([\d.]+).*$/,"$1"),Maxthon:()=>s.replace(/^.*Maxthon\/([\d.]+).*$/,"$1"),QQBrowser:()=>s.replace(/^.*QQBrowser\/([\d.]+).*$/,"$1"),QQ:()=>s.replace(/^.*QQ\/([\d.]+).*$/,"$1"),Baidu:()=>s.replace(/^.*BIDUBrowser[\s/]([\d.]+).*$/,"$1"),UC:()=>s.replace(/^.*UC?Browser\/([\d.]+).*$/,"$1"),Sogou:()=>s.replace(/^.*SE ([\d.X]+).*$/,"$1").replace(/^.*SogouMobileBrowser\/([\d.]+).*$/,"$1"),"2345Explorer":()=>s.replace(/^.*2345Explorer\/([\d.]+).*$/,"$1"),TheWorld:()=>s.replace(/^.*TheWorld ([\d.]+).*$/,"$1"),MIUI:()=>s.replace(/^.*MiuiBrowser\/([\d.]+).*$/,"$1"),Quark:()=>s.replace(/^.*Quark\/([\d.]+).*$/,"$1"),Qiyu:()=>s.replace(/^.*Qiyu\/([\d.]+).*$/,"$1"),Wechat:()=>s.replace(/^.*MicroMessenger\/([\d.]+).*$/,"$1"),Taobao:()=>s.replace(/^.*AliApp\(TB\/([\d.]+).*$/,"$1"),Alipay:()=>s.replace(/^.*AliApp\(AP\/([\d.]+).*$/,"$1"),Weibo:()=>s.replace(/^.*weibo__([\d.]+).*$/,"$1"),Douban:()=>s.replace(/^.*com.douban.frodo\/([\d.]+).*$/,"$1"),Suning:()=>s.replace(/^.*SNEBUY-APP([\d.]+).*$/,"$1"),iQiYi:()=>s.replace(/^.*IqiyiVersion\/([\d.]+).*$/,"$1")};return i.version="",h[i.browser]&&(i.version=h[i.browser](),i.version===s&&(i.version="")),i.version.indexOf(".")&&(i.version=i.version.substring(0,i.version.indexOf("."))),"iOS"===i.os&&s.includes("iPad")?i.os="iPadOS":"Edge"!==i.browser||s.includes("Edg")?"MIUI"===i.browser?i.os="Android":"Chrome"===i.browser&&Number(i.version)>27||"Opera"===i.browser&&Number(i.version)>12||"Yandex"===i.browser?i.engine="Blink":void 0===i.browser&&(i.browser="Unknow App"):i.engine="EdgeHTML",i}(this.data.ua);return{browser:`${e.browser} ${e.version}`,os:`${e.os} ${e.osVersion}`}}getOpts(){return this.opts}}class Bn{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=At(``),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 Fn{constructor(){g(this,"instance"),g(this,"onReachedBottom",null),g(this,"opt")}create(e){return this.opt=e,this.instance=new Bn({pageSize:e.pageSize,onClick:t=>k(this,null,(function*(){e.ctx.fetch({offset:t})})),text:zt("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 Nn{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=At('
    \n
    \n
    \n \n
    \n \n
    \n \n
    \n
    \n
    '),this.$input=this.$el.querySelector(".atk-input"),this.$input.value=`${this.page}`,this.$input.oninput=()=>this.input(),this.$input.onkeydown=e=>this.keydown(e),this.$prevBtn=this.$el.querySelector(".atk-btn-prev"),this.$nextBtn=this.$el.querySelector(".atk-btn-next"),this.$prevBtn.onclick=()=>this.prev(),this.$nextBtn.onclick=()=>this.next(),this.checkDisabled()}get pageSize(){return this.opts.pageSize}get offset(){return this.pageSize*(this.page-1)}get maxPage(){return Math.ceil(this.total/this.pageSize)}update(e,t){this.page=Math.ceil(e/this.pageSize)+1,this.total=t,this.setInput(this.page),this.checkDisabled()}setInput(e){this.$input.value=`${e}`}input(e=!1){window.clearTimeout(this.inputTimer);const t=this.$input.value.trim(),n=()=>{if(""===t)return void this.setInput(this.page);let e=Number(t);Number.isNaN(e)||e<1?this.setInput(this.page):(e>this.maxPage&&(this.setInput(this.maxPage),e=this.maxPage),this.change(e))};e?n():this.inputTimer=window.setTimeout((()=>n()),800)}prev(){const e=this.page-1;e<1||this.change(e)}next(){const e=this.page+1;e>this.maxPage||this.change(e)}getHasMore(){return this.page+1<=this.maxPage}change(e){this.page=e,this.opts.onChange(this.offset),this.setInput(e),this.checkDisabled()}checkDisabled(){this.page+1>this.maxPage?this.$nextBtn.classList.add("atk-disabled"):this.$nextBtn.classList.remove("atk-disabled"),this.page-1<1?this.$prevBtn.classList.add("atk-disabled"):this.$prevBtn.classList.remove("atk-disabled")}keydown(e){const t=e.keyCode||e.which;if(38===t){const e=Number(this.$input.value)+1;if(e>this.maxPage)return;this.setInput(e),this.input()}else if(40===t){const e=Number(this.$input.value)-1;if(e<1)return;this.setInput(e),this.input()}else 13===t&&this.input(!0)}setLoading(e){e?Yt(this.$el):Xt(this.$el)}}class Wn{constructor(){g(this,"instance")}create(e){return this.instance=new Nn(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 zn(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.count:t.data.roots_count),n):n}const Hn=e=>{let t=null;e.watchConf(["pagination","locale"],(n=>{const s=e.get("list");t&&t.dispose(),t=function(e){return e.pagination.readMore?new Fn:new Wn}(n);const{offset:i,total:r}=zn(e),o=t.create({ctx:e,pageSize:n.pagination.pageSize,total:r,readMoreAutoLoad:n.pagination.autoLoad});s.$commentsWrap.after(o),null==t||t.update(i,r)})),e.on("list-loaded",(n=>{const{offset:s,total:i}=zn(e);null==t||t.update(s,i)})),e.on("list-fetch",(n=>{e.getData().getComments().length>0&&(null==t?void 0:t.getIsClearComments(n))&&e.getData().clearComments()})),e.on("list-failed",(()=>{var e;null==(e=null==t?void 0:t.showErr)||e.call(t,zt("loadFail"))})),e.on("list-fetch",(e=>{null==t||t.setLoading(!0)})),e.on("list-fetched",(({params:e})=>{null==t||t.setLoading(!1)}))};class Qn extends dn{constructor(e){super(e),g(this,"$commentsWrap"),g(this,"commentNodes",[]),this.$el=At('
    \n
    \n
    \n
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n'),this.$commentsWrap=this.$el.querySelector(".atk-list-comments-wrap"),Hn(e),this.initCrudEvents()}getCommentsWrapEl(){return this.$commentsWrap}getCommentNodes(){return this.commentNodes}getListLayout({forceFlatMode:e}={}){return new vn({$commentsWrap:this.$commentsWrap,nestSortBy:this.ctx.conf.nestSort,nestMax:this.ctx.conf.nestMax,flatMode:"boolean"==typeof e?e:this.ctx.conf.flatMode,createCommentNode:(t,n)=>{const s=function(e,t,n,s){const i=new Dn(t,{onAfterRender:()=>{e.trigger("comment-rendered",i)},onDelete:t=>{e.getData().deleteComment(t.getID())},replyTo:n,flatMode:"boolean"==typeof(null==s?void 0:s.forceFlatMode)?null==s?void 0:s.forceFlatMode:e.conf.flatMode,gravatar:e.conf.gravatar,nestMax:e.conf.nestMax,heightLimit:e.conf.heightLimit,avatarURLBuilder:e.conf.avatarURLBuilder,scrollRelativeTo:e.conf.scrollRelativeTo,vote:e.conf.vote,voteDown:e.conf.voteDown,uaBadge:e.conf.uaBadge,getApi:()=>e.getApi(),replyComment:(t,n)=>e.replyComment(t,n),editComment:(t,n)=>e.editComment(t,n)});return i.render(),i}(this.ctx,t,n,{forceFlatMode:e});return this.commentNodes.push(s),s},findCommentNode:e=>this.commentNodes.find((t=>t.getID()===e))})}initCrudEvents(){this.ctx.on("list-load",(e=>{this.getListLayout().import(e)})),this.ctx.on("list-loaded",(e=>{0===e.length&&(this.commentNodes=[],this.$commentsWrap.innerHTML="")})),this.ctx.on("comment-inserted",(e=>{var t;const n=e.rid?null==(t=this.commentNodes.find((t=>t.getID()===e.rid)))?void 0:t.getData():void 0;this.getListLayout().insert(e,n)})),this.ctx.on("comment-deleted",(e=>{const t=this.commentNodes.find((t=>t.getID()===e.id));t?(t.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,Gn;function Kn(){return{init(){Vn=document.body.style.overflow,Gn=document.body.style.paddingRight},unlock(){document.body.style.overflow=Vn,document.body.style.paddingRight=Gn},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 s=e.offsetWidth;return n===s&&(s=t.clientWidth),document.body.removeChild(t),n-s}()+e||0}px`}}}class Zn{constructor(e,t){g(this,"allowMaskClose",!0),g(this,"onAfterHide"),this.$el=e,this.opts=t}setOnAfterHide(e){this.onAfterHide=e}setAllowMaskClose(e){this.allowMaskClose=e}getAllowMaskClose(){return this.allowMaskClose}getEl(){return this.$el}show(){this.opts.onShow(),this.$el.style.display=""}hide(){return k(this,null,(function*(){this.opts.onHide(),this.$el.style.display="none",this.onAfterHide&&this.onAfterHide()}))}destroy(){return k(this,null,(function*(){this.opts.onHide(),this.$el.remove(),this.onAfterHide&&this.onAfterHide()}))}}class Yn{constructor(){g(this,"$wrap"),g(this,"$mask"),g(this,"items",[]),this.$wrap=At(''),this.$mask=this.$wrap.querySelector(".atk-layer-mask")}createItem(e,t){(t=t||this.createItemElement(e)).setAttribute("data-layer-name",e),this.$wrap.appendChild(t);const n=new Zn(t,{onHide:()=>this.hideWrap(t),onShow:()=>this.showWrap()});return this.getMask().addEventListener("click",(()=>{n.getAllowMaskClose()&&n.hide()})),this.items.push(n),n}createItemElement(e){const t=document.createElement("div");return t.classList.add("atk-layer-item"),t.style.display="none",this.$wrap.appendChild(t),t}getWrap(){return this.$wrap}getMask(){return this.$mask}showWrap(){this.$wrap.style.display="block",this.$mask.style.display="block",this.$mask.classList.add("atk-fade-in"),Kn().lock()}hideWrap(e){this.items.map((e=>e.getEl())).filter((t=>t!==e&&t.isConnected&&"none"!==t.style.display)).length>0||(this.$wrap.style.display="none",Kn().unlock())}}class Xn{constructor(e){g(this,"wrap"),this.wrap=new Yn,document.body.appendChild(this.wrap.getWrap()),e.on("unmounted",(()=>{this.wrap.getWrap().remove()})),Kn().init()}getEl(){return this.wrap.getWrap()}create(e,t){return this.wrap.createItem(e,t)}}const Jn="ArtalkUser";class es{constructor(e){g(this,"data"),this.opts=e;const t=JSON.parse(window.localStorage.getItem(Jn)||"{}");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(Jn,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 ts={i18n(e){Wt(e.conf.locale),e.watchConf(["locale"],(e=>{Wt(e.locale)}))},user:e=>new es({onUserChanged:t=>{e.trigger("user-changed",t)}}),layerManager:e=>new Xn(e),checkerLauncher:e=>new cn({getCtx:()=>e,getApi:()=>e.getApi(),onReload:()=>e.reload(),getCaptchaIframeURL:()=>`${e.conf.server}/api/v2/captcha/?t=${+new Date}`}),editor(e){const t=new mn(e);return e.$root.appendChild(t.$el),t},list(e){const t=new Qn(e);return e.$root.appendChild(t.$el),t},sidebarLayer:e=>new fn(e),editorPlugs(){}};function ns(e){return k(this,null,(function*(){yield function(e){return k(this,null,(function*(){yield ss({opt:e,query:"page_comment",containers:[e.countEl,"#ArtalkCount"]})}))}(e);const t=yield function(e){return k(this,null,(function*(){if(!e.pvAdd||!e.pageKey)return;const t=(yield e.getApi().pages.logPv({page_key:e.pageKey,page_title:e.pageTitle,site_name:e.siteName})).data.pv;return{[e.pageKey]:t}}))}(e);yield function(e,t){return k(this,null,(function*(){yield ss({opt:e,query:"page_pv",containers:[e.pvEl,"#ArtalkPv"],cache:t})}))}(e,t)}))}function ss(e){return k(this,null,(function*(){const{opt:t}=e;let n=e.cache||{};const s=function(e){const t=new Set;return new Set(e).forEach((e=>{document.querySelectorAll(e).forEach((e=>t.add(e)))})),t}(e.containers),i=function(e,t,n,s){const i=Array.from(e).map((e=>e.getAttribute(t)||n)).filter((e=>e&&"number"!=typeof s[e]));return[...new Set(i)]}(s,t.pageKeyAttr,t.pageKey,n);if(i.length>0){const s=(yield t.getApi().stats.getStats(e.query,{page_keys:i.join(","),site_name:t.siteName})).data.data;n=u(u({},n),s)}!function(e,t,n){e.forEach((e=>{const s=e.getAttribute("data-page-key"),i=s&&t[s]||n&&t[n]||0;e.innerText=`${Number(i)}`}))}(s,n,t.pageKey)}))}const is="ArtalkContent";class rs{constructor(e){this.kit=e}reqAdd(){return k(this,null,(function*(){return(yield this.kit.useApi().comments.createComment(u({},yield this.getSubmitAddParams()))).data}))}getSubmitAddParams(){return k(this,null,(function*(){const{nick:e,email:t,link:n}=this.kit.useUser().getData(),s=this.kit.useConf();return{content:this.kit.useEditor().getContentFinal(),name:e,email:t,link:n,rid:0,page_key:s.pageKey,page_title:s.pageTitle,site_name:s.site,ua:yield It()}}))}postSubmitAdd(e){this.kit.useGlobalCtx().getData().insertComment(e)}}class os extends un{constructor(e){super(e),g(this,"customs",[]),g(this,"defaultPreset"),this.defaultPreset=new rs(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(`${zt("commentFail")}: ${t.message||String(t)}`,"e")}finally{this.kit.useEditor().hideLoading()}this.kit.useEditor().reset(),this.kit.useGlobalCtx().trigger("editor-submitted")}))}}class as extends un{constructor(e){super(e),g(this,"emoticons",[]),g(this,"loadingTask",null),g(this,"$grpWrap"),g(this,"$grpSwitcher"),g(this,"isListLoaded",!1),g(this,"isImgLoaded",!1),this.kit.useMounted((()=>{this.usePanel('
    '),this.useBtn(``)})),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*(){Yt(this.$panel),this.emoticons=yield this.handleData(this.kit.useConf().emoticons),Xt(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 nn(this.$panel,`[${zt("emoticon")}] Data must be of Array/Object/String type`),Xt(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,s)=>k(this,null,(function*(){if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e))yield n(e);else if("string"==typeof e){const s=yield this.remoteLoad(e);Array.isArray(s)?yield n(s):"object"==typeof s&&t(s)}}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 Xt(this.$panel),console.error("[Emoticons] Load Failed:",t),nn(this.$panel,`[${zt("emoticon")}] ${zt("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 s={name:e,type:n.type,items:[]};n.container.forEach(((t,n)=>{const i=t.icon;if(/<(img|IMG)/.test(i)){const e=/src=["'](.*?)["']/.exec(i);e&&e.length>1&&(t.icon=e[1])}s.items.push({key:t.text||`${e} ${n+1}`,val:t.icon})})),t.push(s)})),t}initEmoticonsList(){this.$grpWrap=At('
    '),this.$panel.append(this.$grpWrap),this.emoticons.forEach(((e,t)=>{const n=At('');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 s=At('');if(n.append(s),t.key&&!new RegExp(`^(${e.name})?\\s?[0-9]+$`).test(t.key)&&s.setAttribute("title",t.key),"image"===e.type){const e=document.createElement("img");e.src=t.val,e.alt=t.key,s.append(e)}else s.innerText=t.val;s.onclick=()=>{"image"===e.type?this.kit.useEditor().insertContent(`:[${t.key}]`):this.kit.useEditor().insertContent(t.val||"")}}))})),this.emoticons.length>1&&(this.$grpSwitcher=At('
    '),this.$panel.append(this.$grpSwitcher),this.emoticons.forEach(((e,t)=>{const n=At("");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,s;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==(s=null==(n=this.$grpSwitcher)?void 0:n.querySelector(`span[data-index="${e}"]`))||s.classList.add("active"),this.changeListHeight()}changeListHeight(){}transEmoticonImageText(e){return this.emoticons&&Array.isArray(this.emoticons)?(this.emoticons.forEach((t=>{"image"===t.type&&Object.entries(t.items).forEach((([t,n])=>{e=e.split(`:[${n.key}]`).join(``)}))})),e):e}}const ls=["png","jpg","jpeg","gif","bmp","svg","webp"];class cs extends un{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=ls.map((e=>`.${e}`)).join(",");const e=this.useBtn(``);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.stopPropagation(),e.preventDefault()},n=t=>{var n;const s=null==(n=t.dataTransfer)?void 0:n.files;(null==s?void 0:s.length)&&(t.preventDefault(),e(s))},s=t=>{var n;const s=null==(n=t.clipboardData)?void 0:n.files;(null==s?void 0:s.length)&&(t.preventDefault(),e(s))};this.kit.useMounted((()=>{this.kit.useUI().$textarea.addEventListener("dragover",t),this.kit.useUI().$textarea.addEventListener("drop",n),this.kit.useUI().$textarea.addEventListener("paste",s)})),this.kit.useUnmounted((()=>{this.kit.useUI().$textarea.removeEventListener("dragover",t),this.kit.useUI().$textarea.removeEventListener("drop",n),this.kit.useUI().$textarea.removeEventListener("paste",s)}))}uploadImg(e){return k(this,null,(function*(){const t=/[^.]+$/.exec(e.name);if(!t||!ls.includes(String(t[0]).toLowerCase()))return;if(!this.kit.useUser().checkHasBasicUserInfo())return void this.kit.useEditor().showNotify(zt("uploadLoginMsg"),"w");let n="\n";""===this.kit.useUI().$textarea.value.trim()&&(n="");const s=`${n}![](Uploading ${e.name}...)`;let i;this.kit.useEditor().insertContent(s);try{const t=this.kit.useConf().imgUploader;i=t?{public_url:yield t(e)}:(yield this.kit.useApi().upload.upload({file:e})).data}catch(r){console.error(r),this.kit.useEditor().showNotify(`${zt("uploadFail")}: ${r.message}`,"e")}if(i&&i.public_url){let e=i.public_url;_t(e)||(e=Ut({base:this.kit.useConf().server,path:e})),this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(s,`${n}![](${e})`))}else this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(s,""))}))}}class ds extends un{constructor(e){super(e),g(this,"isPlugPanelShow",!1),this.kit.useMounted((()=>{this.usePanel('
    '),this.useBtn(``)})),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 hs=[class extends un{constructor(e){super(e);const t=()=>{this.save()};this.kit.useMounted((()=>{const e=window.localStorage.getItem(is)||"";""!==e.trim()&&(this.kit.useEditor().showNotify(zt("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(is,this.kit.useEditor().getContentRaw().trim())}},class extends un{get $inputs(){return this.kit.useEditor().getHeaderInputEls()}constructor(e){super(e);const t={},n={},s=(e,t,n)=>()=>{this.kit.useEvents().trigger(e,{field:n,$input:t})};this.kit.useMounted((()=>{Object.entries(this.$inputs).forEach((([e,i])=>{i.addEventListener("input",t[e]=s("header-input",i,e)),i.addEventListener("change",n[e]=s("header-change",i,e))}))})),this.kit.useUnmounted((()=>{Object.entries(this.$inputs).forEach((([e,s])=>{s.removeEventListener("input",t[e]),s.removeEventListener("change",n[e])}))}))}},class extends un{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=`${zt(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 e=this.kit.useApi(),t="getUserCancelToken";this.query.abortFn=()=>e.abortRequest(t),e.user.getUser(u({},e.getUserFields()),{cancelToken:t}).then((e=>this.onUserInfoFetched(e.data))).catch((e=>{})).finally((()=>{this.query.abortFn=null}))}),400)}onUserInfoFetched(e){var t;e.is_login||this.kit.useUser().logout(),this.kit.useGlobalCtx().getData().updateNotifies(e.notifies),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 un{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 un{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||zt("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`}},os,class extends un{constructor(e){super(e);const t=()=>{this.kit.useEditor().submit()};this.kit.useMounted((()=>{this.kit.useUI().$submitBtn.innerText=this.kit.useConf().sendBtn||zt("send"),this.kit.useUI().$submitBtn.addEventListener("click",t)})),this.kit.useUnmounted((()=>{this.kit.useUI().$submitBtn.removeEventListener("click",t)}))}},pn,class extends un{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(os);if(!e)throw Error("SubmitPlug not initialized");const t=new rs(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().comments.createComment(p(u({},yield t.getSubmitAddParams()),{rid:this.comment.id,page_key:this.comment.page_key,page_title:void 0,site_name:this.comment.site_name}))).data})),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();if(!t.$sendReplyBtn){const n=At(`${zt("reply")} `);n.querySelector(".atk-text").innerText=`@${e.nick}`,n.addEventListener("click",(()=>{this.kit.useEditor().resetState()})),t.$stateWrap.append(n),t.$sendReplyBtn=n}this.comment=e,t.$textarea.focus()}cancelReply(){if(!this.comment)return;const e=this.kit.useUI();e.$sendReplyBtn&&(e.$sendReplyBtn.remove(),e.$sendReplyBtn=void 0),this.comment=void 0}},class extends un{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(os);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},t=this.comment;return(yield this.kit.useApi().comments.updateComment(t.id,u(u({},t),e))).data})),post:e=>{this.kit.useGlobalCtx().getData().updateComment(e)}})}))}edit(e){const t=this.kit.useUI();if(!t.$editCancelBtn){const e=At(`${zt("editCancel")}`);e.onclick=()=>{this.kit.useEditor().resetState()},t.$stateWrap.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(zt("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:s}=this.kit.useUser().getData();e.$nick.value=t,e.$email.value=n,e.$link.value=s,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 un{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(At(`
    ${zt("onlyAdminCanReply")}
    `)),this.kit.useUser().getData().isAdmin?(this.kit.useUI().$textarea.style.display="",this.kit.useUI().$bottom.style.display=""):(this.kit.useUI().$textarea.style.display="none",this.kit.useEvents().trigger("panel-close"),this.kit.useUI().$bottom.style.display="none")}},as,cs,ds];class us{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 ps{constructor(e){g(this,"plugs",[]),g(this,"openedPlug",null),g(this,"events",new Ht),this.editor=e;let t=!1;this.editor.ctx.watchConf(["imgUpload","emoticons","preview","editorTravel","locale"],(e=>{t&&this.getEvents().trigger("unmounted"),this.clear(),function(e){const t=new Map;return t.set(cs,e.imgUpload),t.set(as,e.emoticons),t.set(ds,e.preview),t.set(pn,e.editorTravel),hs.filter((e=>!t.has(e)||!!t.get(e)))}(e).forEach((e=>{const t=new us(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 Ht,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 gs="2.8.7";function ms(e){const t=At('

    ');if(t.querySelector(".error-message").innerText=`${zt("listLoadFailMsg")}\n${e.errMsg}`,e.retryFn){const n=At(`${zt("listRetry")}`);n.onclick=()=>e.retryFn&&e.retryFn(),t.appendChild(n)}if(e.onOpenSidebar){const n=At(` | ${zt("openName",{name:zt("ctrlCenter")})}`);t.appendChild(n),n.onclick=()=>e.onOpenSidebar&&e.onOpenSidebar()}nn(e.$err,t)}let fs=!1;let ks;function ys(e,t){const n="atk-dark-mode";e.forEach((e=>{t?e.classList.add(n):e.classList.remove(n)}))}const vs=[e=>{e.watchConf(["imgLazyLoad","markedOptions"],(t=>{!function(e){try{if(!Me.name)return}catch(t){return}Me.setOptions(u(u({renderer:kt({imgLazyLoad:e.imgLazyLoad})},xt),e.markedOptions)),bt=Me}({markedOptions:e.getConf().markedOptions,imgLazyLoad:e.getConf().imgLazyLoad})})),e.watchConf(["markedReplacers"],(e=>{var t;e.markedReplacers&&(t=e.markedReplacers,wt=t)}))},e=>{const t=e.get("editor"),n=new ps(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});const s={limit:n.limit,offset:n.offset,flat_mode:n.flatMode,page_key:e.getConf().pageKey,site_name:e.getConf().site};n.paramsModifier&&n.paramsModifier(s),e.getApi().comments.getComments(u(u({},s),e.getApi().getUserFields())).then((({data:t})=>{e.getData().setListLastFetch({params:n,data:t}),e.getData().loadComments(t.comments),e.getData().updatePage(t.page),n.onSuccess&&n.onSuccess(t),e.trigger("list-fetched",{params:n,data:t})})).catch((t=>{const s={msg:t.msg||String(t),data:t.data};throw n.onError&&n.onError(s),e.trigger("list-failed",s),e.trigger("list-fetched",{params:n,error:s}),t})).finally((()=>{e.getData().setLoading(!1)}))}))},e=>{e.on("list-fetch",(t=>{const n=e.get("list");0===t.offset&&Jt(!0,n.$el)})),e.on("list-fetched",(()=>{Jt(!1,e.get("list").$el)}))},e=>{e.on("comment-rendered",(t=>{if(!0===e.conf.listUnreadHighlight){const n=e.getData().getNotifies(),s=n.find((e=>e.comment_id===t.getID()));s?(t.getRender().setUnread(!0),t.getRender().setOpenAction((()=>{window.open(s.read_link),e.getData().updateNotifies(n.filter((e=>e.comment_id!==t.getID())))}))):t.getRender().setUnread(!1)}})),e.on("list-goto",(t=>{const n=Pt("atk_notify_key");n&&e.getApi().notifies.markNotifyRead(t,n).then((()=>{e.getData().updateNotifies(e.getData().getNotifies().filter((e=>e.comment_id!==t)))}))}))},e=>{let t;e.on("mounted",(()=>{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().pages.updatePage(t.id,t).then((({data:t})=>{e.getData().updatePage(t)})).catch((t=>{e.editorShowNotify(`${zt("editFail")}: ${t.message||String(t)}`,"e")})).finally((()=>{e.editorHideLoading()}))}(e,t)}))})),e.on("page-loaded",(n=>{var s,i;const r=e.get("editor");!0===(null==n?void 0:n.admin_only)?(null==(s=r.getPlugs())||s.getEvents().trigger("editor-close"),t&&(t.innerText=zt("openComment"))):(null==(i=r.getPlugs())||i.getEvents().trigger("editor-open"),t&&(t.innerText=zt("closeComment")))})),e.on("list-loaded",(t=>{e.editorResetState()}))},e=>{e.on("list-loaded",(()=>{(()=>{var t,n;const s=e.get("list").$el.querySelector(".atk-comment-count .atk-text");if(!s)return;const i=Lt(zt("counter",{count:`${Number(null==(n=null==(t=e.getData().getListLastFetch())?void 0:t.data)?void 0:n.count)||0}`}));s.innerHTML=i.replace(/(\d+)/,'$1')})()})),e.on("comment-inserted",(()=>{const t=e.getData().getListLastFetch();(null==t?void 0:t.data)&&(t.data.count+=1)})),e.on("comment-deleted",(()=>{const t=e.getData().getListLastFetch();(null==t?void 0:t.data)&&(t.data.count-=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?zt("ctrlCenter"):zt("msgCenter"))}else t.classList.add("atk-hide")};e.watchConf(["locale"],(s=>{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("mounted",(()=>{const n=e.get("list");t=n.$el.querySelector(".atk-unread-badge")})),e.on("notifies-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(At(''));let s=0;const i=(e,t,n,i)=>{i(),s=e,r.querySelectorAll(".active").forEach((e=>{e.classList.remove("active")})),t.classList.add("active"),r.style.display="none",setTimeout((()=>{r.style.display=""}),80)},r=At('
      ');n.forEach(((e,t)=>{const[n,o]=e,a=At('
    • '),l=a.querySelector("span");l.innerText=n,l.onclick=()=>{i(t,a,n,o)},r.append(a),t===s&&a.classList.add("active")})),t.append(r)}({$dropdownWrap:e,dropdownList:[[zt("sortLatest"),()=>{t((e=>{e.sort_by="date_desc"}))}],[zt("sortBest"),()=>{t((e=>{e.sort_by="vote"}))}],[zt("sortOldest"),()=>{t((e=>{e.sort_by="date_asc"}))}],[zt("sortAuthor"),()=>{t((e=>{e.view_only_admin=!0}))}]]})};e.watchConf(["listSort","locale"],(t=>{const s=e.get("list").$el.querySelector(".atk-comment-count");s&&(t.listSort?n(s):function(e){var t,n;const{$dropdownWrap:s}=e;s.classList.remove("atk-dropdown-wrap"),null==(t=s.querySelector(".atk-arrow-down-icon"))||t.remove(),null==(n=s.querySelector(".atk-dropdown"))||n.remove()}({$dropdownWrap:s}))}))},e=>{let t=0;const n=({locker:n})=>{const s=function(){const e=window.location.hash.match(/#atk-comment-([0-9]+)/);let t=e&&e[1]&&!Number.isNaN(parseFloat(e[1]))?parseFloat(e[1]):null;t||(t=Number(Pt("atk_comment")));return t||null}();s&&(n&&t===s||(t=s,e.trigger("list-goto",s)))},s=()=>n({locker:!1}),i=()=>n({locker:!0});e.on("mounted",(()=>{window.addEventListener("hashchange",s),e.on("list-loaded",i)})),e.on("unmounted",(()=>{window.removeEventListener("hashchange",s),e.off("list-loaded",i)}))},e=>{e.on("list-goto",(t=>k(this,null,(function*(){let n=e.getCommentNodes().find((e=>e.getID()===t));if(!n){const s=(yield e.getApi().comments.getComment(t)).data;e.get("list").getListLayout({forceFlatMode:!0}).insert(s.comment,s.reply_comment),n=e.getCommentNodes().find((e=>e.getID()===t))}n&&n.focus()}))))},e=>{e.on("list-loaded",(t=>{const n=e.get("list"),s=t.length<=0;let i=n.getCommentsWrapEl().querySelector(".atk-list-no-comment");s?i||(i=At('
      '),i.innerHTML=pt(n.ctx.conf.noComment||n.ctx.$t("noComment")),n.getCommentsWrapEl().appendChild(i)):null==i||i.remove()}))},e=>{e.on("mounted",(()=>{const t=e.get("list").$el.querySelector(".atk-copyright");t&&(t.innerHTML=`Powered By Artalk`)}))},e=>{let t=null;e.on("mounted",(()=>{t=window.setInterval((()=>{e.get("list").$el.querySelectorAll("[data-atk-comment-date]").forEach((t=>{const n=t.getAttribute("data-atk-comment-date");t.innerText=Ot(new Date(Number(n)),e.$t)}))}),3e4)})),e.on("unmounted",(()=>{t&&window.clearInterval(t)}))},e=>{e.on("list-fetch",(()=>{nn(e.get("list").$el,null)})),e.on("list-failed",(t=>{ms({$err:e.get("list").$el,errMsg:t.msg,errData:t.data,retryFn:()=>e.fetch({offset:0})})}))},e=>{let t=null;const n=()=>{null==t||t.disconnect(),t=null};e.on("list-loaded",(()=>{n();const s=e.get("list").getCommentsWrapEl().childNodes,i=s.length>2?s[s.length-2]:null;i&&("IntersectionObserver"in window?(s=>{const i=e.conf.scrollRelativeTo&&e.conf.scrollRelativeTo()||null;t=new IntersectionObserver((([t])=>{t.isIntersecting&&(n(),e.trigger("list-reach-bottom"))}),{threshold:.9,root:i}),t.observe(s)})(i):console.warn("IntersectionObserver api not supported"))})),e.on("unmounted",(()=>{n()}))},e=>{const t=()=>{const t=e.get("list"),n=e.conf.scrollRelativeTo&&e.conf.scrollRelativeTo();(n||window).scroll({top:Rt(t.$el,n).top,left:0})};e.on("mounted",(()=>{e.on("list-goto-first",t)})),e.on("unmounted",(()=>{e.off("list-goto-first",t)}))}],e=>{e.on("list-fetch",(t=>{if(0!==t.offset)return;const n=e.getApi().getUserFields();n&&e.getApi().notifies.getNotifies(n).then((t=>{e.getData().updateNotifies(t.data.notifies)}))}))},e=>{e.watchConf(["site","pageKey","pageTitle","countEl","pvEl","statPageKeyAttr"],(t=>{ns({getApi:()=>e.getApi(),siteName:t.site,pageKey:t.pageKey,pageTitle:t.pageTitle,countEl:t.countEl,pvEl:t.pvEl,pageKeyAttr:t.statPageKeyAttr,pvAdd:"boolean"!=typeof e.conf.pvAdd||e.conf.pvAdd})}))},e=>{e.watchConf(["apiVersion","versionCheck"],(t=>{const n=e.get("list");t.apiVersion&&t.versionCheck&&!fs&&function(e,t,n){const s=function(e,t){const n=e.split("."),s=t.split(".");for(let i=0;i<3;i++){const e=Number(n[i]),t=Number(s[i]);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===s)return;const i=At(`
      ${zt("updateMsg",{name:zt(s<0?"frontend":"backend")})} ${zt("currentVersion")}: ${zt("frontend")} ${t} / ${zt("backend")} ${n}
      `),r=At(`${zt("ignore")}`);r.onclick=()=>{i.remove(),fs=!0},i.append(r),e.$el.parentElement.prepend(i)}(n,gs,t.apiVersion)}))},e=>{let t;const n=n=>{const s=[e.$root,e.get("layerManager").getEl()];ks||(ks=window.matchMedia("(prefers-color-scheme: dark)")),"auto"===n?(t||(t=e=>ys(s,e.matches),ks.addEventListener("change",t)),ys(s,ks.matches)):(t&&(ks.removeEventListener("change",t),t=void 0),ys(s,n))};e.watchConf(["darkMode"],(e=>n(e.darkMode))),e.on("created",(()=>n(e.conf.darkMode))),e.on("unmounted",(()=>{t&&(null==ks||ks.removeEventListener("change",t)),t=void 0}))}],$s=new Set([...vs]);function bs(e){return k(this,null,(function*(){var t;const n=new Set,s=t=>{t.forEach((t=>{"function"!=typeof t||n.has(t)||(t(e),n.add(t))}))};s($s);const{data:i}=yield e.getApi().conf.conf().catch((t=>{throw function(e,t){var n;let s="";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}`};s=`sites|${JSON.stringify(t)}`}ms({$err:e.get("list").$el,errMsg:t.msg||String(t),errData:t.data,retryFn:()=>bs(e),onOpenSidebar:e.get("user").getData().isAdmin?()=>e.showSidebar({view:s}):void 0})}(e,t),t}));let r={apiVersion:null==(t=i.version)?void 0:t.version};if(e.conf.useBackendConf){if(!i.frontend_conf)throw new Error("The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled");r=u(u({},r),function(e){const t=["el","pageKey","pageTitle","server","site","pvEl","countEl","statPageKeyAttr"];return Object.keys(e).forEach((n=>{t.includes(n)&&delete e[n],"darkMode"===n&&"auto"!==e[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}(i.frontend_conf))}e.conf.remoteConfModifier&&e.conf.remoteConfModifier(r),r.pluginURLs&&(yield function(e,t){return k(this,null,(function*(){const n=new Set;if(!e||!Array.isArray(e))return n;const s=[];return e.forEach((e=>{/^(http|https):\/\//.test(e)||(e=`${t.replace(/\/$/,"")}/${e.replace(/^\//,"")}`),s.push(new Promise(((t,n)=>{if(document.querySelector(`script[src="${e}"]`))return void t();const s=document.createElement("script");s.src=e,document.head.appendChild(s),s.onload=()=>t(),s.onerror=e=>n(e)})))})),yield Promise.all(s),Object.values(window.ArtalkPlugins||{}).forEach((e=>{"function"==typeof e&&n.add(e)})),n}))}(r.pluginURLs,e.conf.server).then((e=>{s(e)})).catch((e=>{console.error("Failed to load plugin",e)}))),e.trigger("created"),e.updateConf(r),e.trigger("mounted"),e.conf.remoteConfModifier||e.fetch({offset:0})}))}class ws{constructor(e){g(this,"ctx");const t=Vt(e,!0);this.ctx=new Zt(t),Object.entries(ts).forEach((([e,t])=>{const n=t(this.ctx);n&&this.ctx.inject(e,n)})),bs(this.ctx)}getConf(){return this.ctx.getConf()}getEl(){return this.ctx.$root}update(e){return this.ctx.updateConf(e),this}reload(){this.ctx.reload()}destroy(){for(this.ctx.trigger("unmounted");this.ctx.$root.firstChild;)this.ctx.$root.removeChild(this.ctx.$root.firstChild)}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 ws(e)}static use(e){$s.add(e)}static loadCountWidget(e){const t=Vt(e,!0);ns({getApi:()=>new C(Gt(t)),siteName:t.site,countEl:t.countEl,pvEl:t.pvEl,pageKeyAttr:t.statPageKeyAttr,pvAdd:!1})}get $root(){return this.ctx.$root}get conf(){return this.ctx.getConf()}}const xs=ws.init,Cs=ws.use,Es=ws.loadCountWidget;e.default=ws,e.init=xs,e.loadCountWidget=Es,e.use=Cs,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})); +//# sourceMappingURL=Artalk.js.map diff --git a/blog-admin/public/dist/ArtalkLite.css b/blog-admin/public/dist/ArtalkLite.css new file mode 100644 index 00000000..dbfea520 --- /dev/null +++ b/blog-admin/public/dist/ArtalkLite.css @@ -0,0 +1 @@ +@charset "UTF-8";.artalk,.atk-layer-wrap{--at-color-font: #2a2e2e;--at-color-deep: #2a2e2e;--at-color-sub: #757575;--at-color-grey: #747474;--at-color-meta: #697182;--at-color-border: #eceff2;--at-color-light: #4285f4;--at-color-bg: #fff;--at-color-bg-transl: rgba(255, 255, 255, .94);--at-color-bg-grey: #f3f4f5;--at-color-bg-grey-transl: rgba(244, 244, 244, .75);--at-color-bg-light: rgba(29, 161, 242, .1);--at-color-main: #0083ff;--at-color-red: #ff5652;--at-color-pink: #fa5a57;--at-color-yellow: #ff7c37;--at-color-green: #4caf50;--at-color-gradient: linear-gradient(180deg, transparent, rgba(255, 255, 255))}.artalk.atk-dark-mode,.atk-layer-wrap.atk-dark-mode{--at-color-font: #fff;--at-color-deep: #e7e7e7;--at-color-sub: #e7e7e7;--at-color-grey: #fff;--at-color-meta: #fff;--at-color-border: #2d3235;--at-color-light: #687a86;--at-color-bg: #1e2224;--at-color-bg-transl: rgba(30, 34, 36, .95);--at-color-bg-grey: #46494e;--at-color-bg-grey-transl: rgba(8, 8, 8, .95);--at-color-bg-light: rgba(29, 161, 242, .1);--at-color-main: #0083ff;--at-color-red: #ff5652;--at-color-pink: #fa5a57;--at-color-yellow: #ff7c37;--at-color-green: #4caf50;--at-color-gradient: linear-gradient(180deg, transparent, rgba(30, 34, 36, 1))}.atk-comment-wrap{overflow:hidden;position:relative;border-bottom:1px solid transparent}.atk-comment-wrap.atk-flash-once{animation:atkFlashOnce 1s ease-in-out 0s}@keyframes atkFlashOnce{0%{background:#0083ff33}to{background:transparent}}.atk-comment-wrap.atk-unread:before{content:" ";position:absolute;left:0;top:10%;width:3px;height:80%;background:var(--at-color-main)}.atk-comment-wrap.atk-openable{cursor:pointer}.atk-comment-wrap.atk-openable:hover{background:var(--at-color-bg-grey)}.atk-comment-wrap.atk-openable .atk-height-limit:after{background:transparent!important}.atk-comment-wrap:last-child{border-bottom:none}.atk-comment{display:block;padding:10px}.atk-comment>.atk-avatar{display:block;padding:2px 0;float:left}.atk-comment>.atk-avatar img{width:50px;height:50px;border-radius:3px}.atk-comment>.atk-main{display:block;margin-left:63px}.atk-comment>.atk-main>.atk-header{line-height:1.5;font-size:13px;margin-bottom:.5em;overflow:hidden;position:relative;display:flex;flex-wrap:wrap;align-items:center}.atk-comment>.atk-main>.atk-header .atk-item{display:flex;align-items:center;margin-top:2px;margin-bottom:2px;color:var(--at-color-meta)}.atk-comment>.atk-main>.atk-header .atk-item:not(:last-child){margin-right:6px}.atk-comment>.atk-main>.atk-header .atk-item.atk-nick,.atk-comment>.atk-main>.atk-header .atk-item.atk-nick a{font-size:14px;color:var(--at-color-main);text-decoration:none}.atk-comment>.atk-main>.atk-header .atk-item.atk-reply-at{margin-left:2px}.atk-comment>.atk-main>.atk-header .atk-item.atk-reply-at>.atk-arrow:before{content:"";vertical-align:middle;transform:rotate(90deg);border-bottom:4px solid var(--at-color-grey);border-left:3px solid transparent;border-right:3px solid transparent;display:inline-block;margin-top:-1px}.atk-comment>.atk-main>.atk-header .atk-item.atk-reply-at>.atk-nick{color:var(--at-color-main);cursor:pointer;margin-left:6px}.atk-comment>.atk-main>.atk-header .badge,.atk-comment>.atk-main>.atk-header .atk-ua,.atk-comment>.atk-main>.atk-header .atk-pinned-badge,.atk-comment>.atk-main>.atk-header .atk-region-badge,.atk-comment>.atk-main>.atk-header .atk-badge{display:inline-block;color:var(--at-color-meta);background:var(--at-color-bg-grey);padding:0 6px;line-height:17px;border-radius:3px}.atk-comment>.atk-main>.atk-header .badge:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-ua:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-pinned-badge:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-region-badge:not(:last-child),.atk-comment>.atk-main>.atk-header .atk-badge:not(:last-child){margin-right:6px}.atk-comment>.atk-main>.atk-header .atk-badge-wrap>*:last-child{margin-right:6px}.atk-comment>.atk-main>.atk-header .atk-badge{color:#fff}.atk-comment>.atk-main>.atk-header .atk-pinned-badge{color:#fff;background:#f44336}.atk-comment>.atk-main>.atk-header .atk-verified-icon{height:1.4em;width:1.4em;background-repeat:no-repeat;background-position:center;background-size:contain;display:block;background-image:url('data:image/svg+xml,')}@media only screen and (max-width: 768px){.atk-comment>.atk-main>.atk-header .atk-ua-wrap{display:block}}.atk-comment>.atk-main>.atk-body{display:block;overflow:hidden;position:relative}.atk-comment>.atk-main>.atk-body img{max-width:100%}.atk-comment>.atk-main>.atk-body>.atk-content{word-break:break-word}.atk-comment>.atk-main>.atk-body>.atk-content.atk-type-collapsed{border:3px solid var(--at-color-bg-grey);border-bottom:0;padding:5px 10px;border-radius:6px 6px 0 0;margin-bottom:-5px}.atk-comment>.atk-main>.atk-body>.atk-content>*:first-child{margin-top:0}.atk-comment>.atk-main>.atk-body>.atk-content>*:last-child{margin-bottom:0}.atk-comment>.atk-main>.atk-body>.atk-content .atk-height-limit-btn{bottom:5px}.atk-comment>.atk-main>.atk-body>.atk-pending{color:var(--at-color-meta);margin:3px 0;font-size:13px;padding:10px 18px;display:block;background:var(--at-color-bg-grey);border-left:4px solid #f44336}.atk-comment>.atk-main>.atk-body>.atk-reply-to{padding:5px 15px;border-left:3px solid var(--at-color-border);margin-bottom:10px;position:relative;margin-top:10px}.atk-comment>.atk-main>.atk-body>.atk-reply-to .atk-meta{font-size:15px}.atk-comment>.atk-main>.atk-body>.atk-reply-to .atk-meta .atk-nick{color:var(--at-color-main)}.atk-comment>.atk-main>.atk-body>.atk-reply-to .atk-content{margin-top:5px}.atk-comment>.atk-main>.atk-body>.atk-collapsed{margin:3px 0;font-size:13px;padding:10px 18px;display:block;background:var(--at-color-bg-grey);border-radius:6px}.atk-comment>.atk-main>.atk-body>.atk-collapsed .atk-text{color:var(--at-color-meta)}.atk-comment>.atk-main>.atk-body>.atk-collapsed .atk-show-btn{color:var(--at-color-main);cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-left:3px}.atk-comment>.atk-main>.atk-body>.atk-collapsed .atk-show-btn:hover{color:var(--at-color-main)}.atk-comment>.atk-main>.atk-footer{margin-top:5px}.atk-comment>.atk-main>.atk-footer .atk-actions{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.atk-comment>.atk-main>.atk-footer .atk-actions>span{color:var(--at-color-meta);font-size:13px;line-height:25px;display:inline-flex;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.atk-comment>.atk-main>.atk-footer .atk-actions>span.atk-error,.atk-comment>.atk-main>.atk-footer .atk-actions>span.atk-error:hover{color:var(--at-color-red)}.atk-comment>.atk-main>.atk-footer .atk-actions>span:not(:last-child):not(.atk-hide){margin-right:16px}.atk-comment>.atk-main>.atk-footer .atk-actions>span:hover{color:var(--at-color-deep)}.atk-comment .atk-height-limit:after{position:absolute;z-index:1;display:block;overflow:hidden;width:100%;content:" ";bottom:0;height:80px;background:var(--at-color-gradient)}.atk-comment .atk-height-limit-btn{z-index:2;position:absolute;left:50%;bottom:10px;transform:translate(-50%);cursor:pointer;border:1px solid var(--at-color-border);border-radius:6px;background:var(--at-color-bg);padding:1px 20px;font-size:15px;color:var(--at-color-meta);-webkit-user-select:none;-moz-user-select:none;user-select:none}.atk-comment .atk-height-limit-btn:hover{background:var(--at-color-bg-grey)}.atk-comment .atk-height-limit .atk-height-limit .atk-height-limit-btn{display:none}.atk-comment .atk-height-limit-scroll{margin-top:10px;overflow-y:auto;background:linear-gradient(var(--at-color-bg) 1px,transparent 1px calc(100% - 1px)) center top,linear-gradient(transparent calc(100% - 1px),var(--at-color-bg) calc(100% - 1px) 1px) center bottom,linear-gradient(var(--at-color-border) 1px,transparent 1px calc(100% - 1px)) center top,linear-gradient(transparent calc(100% - 1px),var(--at-color-border) calc(100% - 1px) 1px) center bottom;background-repeat:no-repeat;background-color:transparent;background-size:100% 1px,100% 1px,100% 1px,100% 1px;background-attachment:local,local,scroll,scroll}.atk-comment-children>.atk-comment-wrap{margin-top:10px;border-left:1px dashed transparent;border-bottom-color:transparent}.atk-comment-children>.atk-comment-wrap:not(:last-child){margin-bottom:10px}.atk-comment-children>.atk-comment-wrap>.atk-comment{padding:0}.atk-comment-children>.atk-comment-wrap>.atk-comment>.atk-avatar img{width:36px;height:36px}.atk-comment-children>.atk-comment-wrap>.atk-comment>.atk-main{margin-left:47px}.artalk>.atk-list{position:relative}.artalk>.atk-list>.atk-list-header{display:flex;flex-direction:row;padding:10px 17px}.artalk>.atk-list>.atk-list-header .atk-text{display:inline-block}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap{position:relative;cursor:pointer}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-arrow-down-icon{cursor:pointer;vertical-align:middle;border-top:5px solid var(--at-color-grey);border-left:3px solid transparent;border-right:3px solid transparent;margin-top:-1px;margin-left:.8rem;display:inline-block}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap:hover .atk-dropdown{display:block}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown{z-index:3;display:none;height:auto!important;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;width:100%;background-color:var(--at-color-bg);padding:.6rem 0;border:1px solid var(--at-color-border);text-align:center;border-radius:6px;white-space:nowrap;margin:0;list-style:none}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item span,.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item a{display:block;line-height:2rem;position:relative;border-bottom:none;font-weight:400;padding:0 1.5rem}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item span:hover,.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item a:hover{color:var(--at-color-main)}.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item.active span,.artalk>.atk-list>.atk-list-header .atk-dropdown-wrap .atk-dropdown-item a{color:var(--at-color-main)}.artalk>.atk-list>.atk-list-header .atk-comment-count{font-size:15px}.artalk>.atk-list>.atk-list-header .atk-comment-count .atk-comment-count-num{font-size:22px;margin-right:4px}.artalk>.atk-list>.atk-list-header .atk-right-action{display:flex;flex:1;flex-direction:row;align-items:center;justify-content:flex-end}.artalk>.atk-list>.atk-list-header .atk-right-action>span{font-size:14px;color:var(--at-color-meta);cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:relative}.artalk>.atk-list>.atk-list-header .atk-right-action>span.atk-on,.artalk>.atk-list>.atk-list-header .atk-right-action>span.atk-on *{color:var(--at-color-main)}.artalk>.atk-list>.atk-list-header .atk-right-action>span:not(:last-child):not(.atk-hide){margin-right:10px;padding-right:10px}.artalk>.atk-list>.atk-list-header .atk-right-action>span .atk-unread-badge{position:absolute;top:-5px;left:-6px;color:#fff;background:var(--at-color-pink);text-align:center;min-width:16px;height:16px;padding:0 3px;border-radius:8px;line-height:16px;font-size:12px}.artalk>.atk-list>.atk-list-body{min-height:150px}.artalk>.atk-list>.atk-list-footer{text-align:right}@media only screen and (max-width: 768px){.artalk>.atk-list>.atk-list-footer{float:initial;text-align:center}}.artalk>.atk-list>.atk-list-footer .atk-copyright{display:block;font-size:12px;color:var(--at-color-meta);padding-right:15px}.artalk>.atk-list>.atk-list-footer .atk-copyright a{color:var(--at-color-main);text-decoration:none}.atk-list-no-comment{height:150px;display:flex;font-size:19px;justify-content:center;align-items:center;word-break:break-word;text-align:center}.atk-list-read-more{border-top:1px dashed var(--at-color-border);margin-top:28px;padding-bottom:25px}@media only screen and (max-width: 768px){.atk-list-read-more{padding-bottom:10px}}.atk-list-read-more.atk-err .atk-text{color:var(--at-color-red)!important}.atk-list-read-more .atk-list-read-more-inner{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:0 15px;font-size:14px;border-radius:6px;border:1px solid transparent;display:flex;height:30px;flex-direction:row;place-content:center;align-items:center;width:120px;margin:-15px auto 0;background:var(--at-color-bg);border-color:var(--at-color-border)}.atk-list-read-more .atk-list-read-more-inner>.atk-loading-icon{height:15px;width:15px}.atk-list-read-more .atk-list-read-more-inner>.atk-text{color:var(--at-color-meta)}.atk-list-read-more .atk-list-read-more-inner:hover{background:var(--at-color-bg-grey)}.atk-pagination{display:flex;flex-direction:row;justify-content:center;padding:10px 0;position:relative}.atk-pagination>.atk-btn,.atk-pagination>.atk-input{height:30px;border:1px solid var(--at-color-border);border-radius:3px;padding:0 5px;text-align:center;background:var(--at-color-bg)}.atk-pagination>.atk-btn{-webkit-user-select:none;-moz-user-select:none;user-select:none;width:60px;cursor:pointer;display:flex;justify-content:center;align-items:center}.atk-pagination>.atk-btn:hover{background:var(--at-color-bg-grey)}.atk-pagination>.atk-btn.atk-disabled{color:var(--at-color-sub)}.atk-pagination>.atk-btn.atk-disabled:hover{cursor:default;background:initial}.atk-pagination>.atk-input{background:transparent;color:var(--at-color-font);font-size:18px;width:60px;outline:none}.atk-pagination>.atk-input:focus{border-color:var(--at-color-main)}.atk-pagination>*:not(:last-child){margin-right:10px}.atk-main-editor{position:relative;overflow:hidden;background:var(--at-color-bg);border:1px solid var(--at-color-border);border-radius:6px;margin-bottom:10px}@media only screen and (max-width: 768px){.atk-main-editor{margin-bottom:7px}}.atk-main-editor.editor-traveling{margin-top:5px;margin-bottom:10px}.atk-main-editor>.atk-header{display:flex;flex-direction:row;padding:10px 14px 0}.atk-main-editor>.atk-header input{flex:1;width:100%;font-size:14px;background:transparent;border:2px solid transparent;border-radius:3px;padding:6px 5px;resize:none;outline:none}.atk-main-editor>.atk-header input:not(:last-child){margin-right:2px}.atk-main-editor>.atk-textarea-wrap{position:relative}.atk-main-editor>.atk-textarea-wrap>.atk-textarea{display:block;overflow:hidden;color:var(--at-color-font);font-size:15px;background-color:var(--at-color-bg);border:2px solid transparent;border-radius:3px;width:100%;min-height:120px;margin-top:2px;padding:10px 20px;resize:none;word-wrap:break-word;outline:none}.atk-main-editor>.atk-textarea-wrap>.atk-comment-closed{pointer-events:none;color:var(--at-color-meta);font-size:12px;background-color:var(--at-color-bg);border-top:1px solid var(--at-color-border);padding:5px 15px;margin-top:10px}.atk-main-editor>.atk-plug-panel-wrap{position:relative;height:180px;width:100%;overflow:hidden;border-top:1px solid var(--at-color-border);animation:.3s both atkFadeIn;transition:.2s height ease-in-out}.atk-main-editor>.atk-bottom{display:flex;flex-direction:row;row-gap:5px;justify-content:space-between;padding:5px;flex-wrap:wrap}.atk-main-editor>.atk-bottom>.atk-item{display:flex;flex-direction:row;align-items:center}.atk-main-editor>.atk-bottom>.atk-bottom-left>.atk-state-wrap{margin-right:5px}.atk-main-editor>.atk-bottom>.atk-bottom-left>.atk-plug-btn-wrap{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;row-gap:5px}.atk-main-editor>.atk-bottom .atk-plug-btn{display:flex;justify-content:center;place-items:center;padding:0 10px;line-height:30px;height:30px;cursor:pointer;color:var(--at-color-grey);font-size:14px;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:3px;word-break:keep-all}.atk-main-editor>.atk-bottom .atk-plug-btn:not(:last-child){margin-right:5px}.atk-main-editor>.atk-bottom .atk-plug-btn:hover{background:var(--at-color-bg-grey)}.atk-main-editor>.atk-bottom .atk-plug-btn.active{color:var(--at-color-main)}.atk-main-editor>.atk-bottom .atk-plug-btn.active svg.markdown path{fill:var(--at-color-main)}.atk-main-editor>.atk-bottom .atk-plug-btn i{display:flex;justify-content:center;place-items:center;color:var(--at-color-grey)}.atk-main-editor>.atk-bottom .atk-plug-btn i:not(:first-child){margin-left:4px}.atk-main-editor>.atk-bottom .atk-state-btn{z-index:2;height:30px;padding:0 0 0 10px;font-size:14px;position:relative;display:flex;flex-direction:row;justify-content:center;place-items:center;background:var(--at-color-bg-grey-transl);cursor:pointer;overflow:hidden;border-radius:3px}.atk-main-editor>.atk-bottom .atk-state-btn:hover .atk-cancel{background:#0000000a}@media only screen and (max-width: 768px){.atk-main-editor>.atk-bottom .atk-state-btn{padding:0}.atk-main-editor>.atk-bottom .atk-state-btn .atk-text-wrap{display:none}}.atk-main-editor>.atk-bottom .atk-state-btn .atk-text-wrap{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 8px 0 2px;max-width:8em}.atk-main-editor>.atk-bottom .atk-state-btn .atk-cancel{display:flex;justify-content:center;place-items:center;padding:0 10px;font-weight:700;height:100%;background:#00000005}.atk-main-editor>.atk-bottom .atk-send-btn{background:var(--at-color-main);color:#fff;font-size:14px;border:none;margin:0;height:30px;min-width:7.3em;cursor:pointer;transition:opacity .3s ease-in-out;outline:none;border-radius:3px}@media only screen and (max-width: 768px){.atk-main-editor>.atk-bottom .atk-send-btn{min-width:6em}}.atk-main-editor>.atk-bottom .atk-send-btn:active{opacity:.9}.atk-main-editor>.atk-notify-wrap{z-index:3;position:absolute;right:-2px;bottom:40px;width:225px;opacity:.83}.atk-sidebar-layer{position:fixed;z-index:99999;top:0;right:0;width:430px;height:100%;background:var(--at-color-bg);transition:transform .45s cubic-bezier(.23,1,.32,1) 0ms;transform:translate(430px)}@media only screen and (max-width: 430px){.atk-sidebar-layer{width:100%}}.atk-sidebar-layer .atk-sidebar-inner{position:relative;height:100%}.atk-sidebar-layer .atk-sidebar-header{position:absolute;top:0;right:0;display:flex;flex-direction:row;align-items:center;z-index:99999}.atk-sidebar-layer .atk-sidebar-header .atk-sidebar-close{display:flex;flex-direction:column;width:60px;height:60px;align-items:center;place-content:center;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-left:10px;font-size:22px}.atk-sidebar-layer .atk-sidebar-header .atk-sidebar-close:hover :after{background-color:#e81123e6}.atk-sidebar-layer .atk-sidebar-iframe-wrap{height:100%;position:relative}.atk-sidebar-layer .atk-sidebar-iframe-wrap iframe{border:0;width:100%;height:100%}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert{z-index:9999;top:50%;left:50%;transform:translate(-50%,-50%);position:absolute;background:var(--at-color-bg);padding:40px 30px;width:80%;text-align:center;border-radius:4px}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert .atk-title{font-size:1.4em;margin-bottom:20px;color:var(--at-color-font)}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert .atk-text{color:var(--at-color-font)}.atk-sidebar-layer .atk-sidebar-iframe-wrap .atk-err-alert .atk-text span{cursor:pointer;color:var(--at-color-main)}.artalk{position:relative;width:100%;min-height:200px}.artalk,.atk-layer-wrap{color:var(--at-color-font);word-wrap:break-word;word-break:break-word}.artalk *,.atk-layer-wrap *{box-sizing:border-box}.artalk input,.artalk textarea,.artalk button,.artalk optgroup,.artalk select,.atk-layer-wrap input,.atk-layer-wrap textarea,.atk-layer-wrap button,.atk-layer-wrap optgroup,.atk-layer-wrap select{font-family:inherit;color:inherit;font-size:inherit}.artalk code,.atk-layer-wrap code{font-family:source code pro,Consolas,Monaco,Menlo,sans-serif;margin:0 .05em;padding:0 .4em;display:inline-block;vertical-align:middle;font-size:.9em;background-color:var(--at-color-bg-grey);color:var(--at-color-font);border-radius:2px}.artalk pre,.atk-layer-wrap pre{margin:10px 0 0;padding:0;line-height:0}.artalk pre code,.atk-layer-wrap pre code{line-height:1.6em;display:block;padding:10px 15px;white-space:pre-wrap!important;background-color:var(--at-color-bg-grey);color:var(--at-color-font);margin:0}.artalk pre code *,.atk-layer-wrap pre code *{font-family:source code pro,Consolas,Monaco,Menlo,sans-serif}.artalk a,.atk-layer-wrap a{color:var(--at-color-main);text-decoration:none}.artalk blockquote,.atk-layer-wrap blockquote{position:static;margin:10px 0;padding:10px 20px;background:var(--at-color-bg-grey);border-left:4px solid #687a86;color:var(--at-color-font)}.artalk p:first-child,.atk-layer-wrap p:first-child{margin-top:0}.artalk p:last-child,.atk-layer-wrap p:last-child{margin-bottom:0}.artalk img,.atk-layer-wrap img{max-width:100%}.artalk table,.atk-layer-wrap table{width:100%;border-collapse:collapse;border-spacing:0;margin-bottom:1.5em;font-size:.96em}.artalk td,.artalk th,.atk-layer-wrap td,.atk-layer-wrap th{text-align:left;padding:4px 8px 4px 10px;border:1px solid var(--at-color-border)}.artalk td,.atk-layer-wrap td{vertical-align:top}.artalk tr:nth-child(2n),.atk-layer-wrap tr:nth-child(2n){background-color:var(--at-color-bg-grey)}.artalk ul,.atk-layer-wrap ul{list-style:disc}.artalk ol,.atk-layer-wrap ol{list-style:decimal}.artalk li+li,.atk-layer-wrap li+li{margin-top:8px}.artalk li>ol,.artalk li>ul,.atk-layer-wrap li>ol,.atk-layer-wrap li>ul{margin:8px 0 0}.atk-hide{display:none!important}.atk-full-layer,.atk-layer-dialog-wrap,.atk-error-layer,.atk-loading{width:100%;height:100%;position:absolute;top:0;left:0;background:var(--at-color-bg);z-index:4;align-items:center;justify-content:center;flex-flow:column;display:flex}.atk-loading-spinner{position:relative;width:50px;height:50px}.atk-loading-spinner svg{animation:atkRotate 2s linear infinite;transform-origin:center center;width:100%;height:100%;position:absolute;top:0;left:0}.atk-loading-spinner svg circle{stroke-dasharray:1,200;stroke-dashoffset:0;animation:atkDash 1.5s ease-in-out infinite,atkColor 6s ease-in-out infinite;stroke-linecap:round}@keyframes atkRotate{to{transform:rotate(360deg)}}@keyframes atkDash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}to{stroke-dasharray:89,200;stroke-dashoffset:-124px}}@keyframes atkColor{0%,to{stroke:#ff5652}40%{stroke:#2196f3}66%{stroke:#32c787}80%,90%{stroke:#ffc107}}@keyframes atkLoadingIconRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.atk-loading-icon{width:18px;height:18px;box-sizing:border-box;border:solid 1px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;animation:atkLoadingIconRotate .4s linear infinite}.atk-fade-in{animation:atkFadeIn both .3s}.atk-fade-out{animation:atkFadeOut both .2s}.atk-rotate{animation:atkRotate 2s linear infinite}@keyframes atkFadeIn{0%{opacity:0}to{opacity:1}}@keyframes atkFadeOut{to{opacity:0}}@keyframes atkRotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.atk-icon:after{display:block;content:"";width:1em;height:1em;background-color:var(--at-color-deep);background-size:contain;background-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;mask-size:contain}.atk-icon-sync:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.99133 4.87635C2.22512 7.64257 2.22512 12.1275 4.99133 14.8937C6.04677 15.9491 7.3524 16.6019 8.71732 16.8519' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M14.4179 15.4815L15.0072 14.8922C17.7734 12.126 17.7734 7.64107 15.0072 4.87486C13.9518 3.81942 12.6461 3.16668 11.2812 2.91664' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M6.17106 4.99252L5.58181 4.40327L4.99255 3.81401H6.17106V4.99252Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M13.8299 15.0084L14.4192 15.5976L15.0084 16.1869H13.8299V15.0084Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.99133 4.87635C2.22512 7.64257 2.22512 12.1275 4.99133 14.8937C6.04677 15.9491 7.3524 16.6019 8.71732 16.8519' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M14.4179 15.4815L15.0072 14.8922C17.7734 12.126 17.7734 7.64107 15.0072 4.87486C13.9518 3.81942 12.6461 3.16668 11.2812 2.91664' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M6.17106 4.99252L5.58181 4.40327L4.99255 3.81401H6.17106V4.99252Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M13.8299 15.0084L14.4192 15.5976L15.0084 16.1869H13.8299V15.0084Z' fill='%23C4C4C4' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E")}.atk-icon-del:after{background-color:var(--at-color-red)!important;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='22' height='22' viewBox='0 0 22 22' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.29167 5.04166L4.81251 5.04166M4.81251 5.04166L4.81251 18.3333C4.81251 18.5865 5.01771 18.7917 5.27084 18.7917L16.7292 18.7917C16.9823 18.7917 17.1875 18.5865 17.1875 18.3333V5.04166M4.81251 5.04166L7.33334 5.04166M17.1875 5.04166L19.7083 5.04166M17.1875 5.04166L14.6667 5.04166M7.33334 5.04166V3.20833L14.6667 3.20833V5.04166M7.33334 5.04166L14.6667 5.04166' stroke='%23D06565' stroke-width='2'/%3E%3Cpath d='M9.16667 8.25V15.125M12.8333 8.25V15.125' stroke='%23D06565' stroke-width='2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='22' height='22' viewBox='0 0 22 22' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.29167 5.04166L4.81251 5.04166M4.81251 5.04166L4.81251 18.3333C4.81251 18.5865 5.01771 18.7917 5.27084 18.7917L16.7292 18.7917C16.9823 18.7917 17.1875 18.5865 17.1875 18.3333V5.04166M4.81251 5.04166L7.33334 5.04166M17.1875 5.04166L19.7083 5.04166M17.1875 5.04166L14.6667 5.04166M7.33334 5.04166V3.20833L14.6667 3.20833V5.04166M7.33334 5.04166L14.6667 5.04166' stroke='%23D06565' stroke-width='2'/%3E%3Cpath d='M9.16667 8.25V15.125M12.8333 8.25V15.125' stroke='%23D06565' stroke-width='2'/%3E%3C/svg%3E")}.atk-icon-edit:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.70618 4.08515L12.6081 7.06376M1.00041 13.021L11.7376 2L14.6392 4.97861L3.90274 16H1L1.00041 13.021Z' stroke='%234E5969' stroke-width='1.5'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='16' height='17' viewBox='0 0 16 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.70618 4.08515L12.6081 7.06376M1.00041 13.021L11.7376 2L14.6392 4.97861L3.90274 16H1L1.00041 13.021Z' stroke='%234E5969' stroke-width='1.5'/%3E%3C/svg%3E")}.atk-icon-yes:after,.atk-icon-check:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.7071 5.75533L9.92197 17.5404L3.29285 10.9113' stroke='%234E5969'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.7071 5.75533L9.92197 17.5404L3.29285 10.9113' stroke='%234E5969'/%3E%3C/svg%3E")}.atk-icon-plus:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.08331 10H17.9166' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M10 2.08334L10 17.9167' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.08331 10H17.9166' stroke='%234E5969' stroke-width='2'/%3E%3Cpath d='M10 2.08334L10 17.9167' stroke='%234E5969' stroke-width='2'/%3E%3C/svg%3E")}.atk-icon-close-slim:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='25' height='25' viewBox='0 0 25 25' fill='none'%3E%3Cpath d='M19.8657 5.13431L12.5 12.5L5.13431 19.8657' stroke='%234E5969'/%3E%3Cpath d='M5.13431 5.13432L12.5 12.5L19.8657 19.8657' stroke='%234E5969'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='25' height='25' viewBox='0 0 25 25' fill='none'%3E%3Cpath d='M19.8657 5.13431L12.5 12.5L5.13431 19.8657' stroke='%234E5969'/%3E%3Cpath d='M5.13431 5.13432L12.5 12.5L19.8657 19.8657' stroke='%234E5969'/%3E%3C/svg%3E")}.atk-icon-arrow-left:after{-webkit-mask-image:url('data:image/svg+xml,');mask-image:url('data:image/svg+xml,')}.atk-icon-no:after,.atk-icon-close:after{-webkit-mask-image:url('data:image/svg+xml,');mask-image:url('data:image/svg+xml,')}.atk-error-layer{background-color:var(--at-color-bg-transl)}.atk-error-layer .atk-error-title{color:var(--at-color-red)}.atk-error-layer .atk-warn-title{color:var(--at-color-yellow)}.atk-error-layer .atk-error-title,.atk-error-layer .atk-warn-title{display:inline-block;padding:0 15px;margin-bottom:20px;font-size:20px;letter-spacing:-.5px}.atk-error-layer .atk-error-text{text-align:center;padding:0 20px}.atk-error-layer .atk-error-text *{color:var(--at-color-deep)}.atk-error-layer .atk-error-text a{color:var(--at-color-meta)}.atk-version-check-notice{background:var(--at-color-bg-grey);border-radius:6px;padding:10px 20px;margin-bottom:10px;font-size:14px}.atk-version-check-notice .atk-info{color:var(--at-color-meta)}.atk-version-check-notice .atk-ignore-btn{cursor:pointer;float:right}.atk-version-check-notice .atk-ignore-btn:hover{opacity:.8}.atk-layer-dialog-wrap{background-color:var(--at-color-bg-transl)}.atk-layer-dialog-wrap>.atk-layer-dialog{width:25%}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-content .atk-captcha-img{cursor:pointer;width:170px;height:auto;margin-right:10px;padding-right:10px;border-right:1px solid var(--at-color-border);vertical-align:bottom}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-content input{width:100%;line-height:34px;background-color:var(--at-color-bg);border:1px solid var(--at-color-border);border-radius:3px;outline:none;padding:0 6px;display:block;margin-top:10px;margin-bottom:5px;text-align:center}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions{display:flex;flex-direction:row}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button{flex:1;display:block;cursor:pointer;border:1px solid var(--at-color-main);background:transparent;color:var(--at-color-main);border-radius:3px;padding:0 15px;line-height:30px;outline:none}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button:active{color:#fff;background:var(--at-color-main)}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button:not(:last-child){margin-right:5px}.atk-layer-dialog-wrap>.atk-layer-dialog>.atk-layer-dialog-actions button.error{color:#fff;background:#ff5652;border-color:#ff5652}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap{position:fixed;z-index:999998;left:0;top:0;height:100vh;width:100vw}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap>iframe{width:100%;height:100%;border:0}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap .atk-close-btn{z-index:999999;position:fixed;top:20px;right:20px;display:flex;flex-direction:column;width:50px;height:50px;align-items:center;place-content:center;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-left:10px}.atk-layer-dialog-wrap>.atk-layer-dialog .atk-checker-iframe-wrap .atk-close-btn:hover .atk-icon-close:after{background-color:#e81123e6}@media only screen and (max-width: 768px){.atk-layer-dialog-wrap>.atk-layer-dialog{width:90%!important}}.atk-notify{display:block;overflow:hidden;background-color:#2c2c2c;color:#fff;border-radius:3px;cursor:pointer;font-size:14px;padding:5px 15px}.atk-notify:not(:last-child){margin-bottom:3px}.atk-notify .atk-notify-content{color:#fff}.atk-layer-wrap .atk-layer-mask{position:fixed;top:0;left:0;width:100%;height:100%;z-index:99998;background:#0000004d}.atk-layer-wrap .atk-layer-item{position:fixed;z-index:99999;top:0;right:0;width:100%;height:100%}.atk-common-action-btn.atk-btn-confirm,.atk-common-action-btn.atk-btn-warn{color:var(--at-color-yellow)!important}.atk-common-action-btn.atk-btn-error{color:var(--at-color-red)!important}.atk-common-action-btn.atk-btn-success{color:var(--at-color-green)!important}img[atk-emoticon]{max-height:60px;display:initial}.atk-slim-scrollbar::-webkit-scrollbar,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar{width:4px;height:4px;background:transparent}.atk-slim-scrollbar::-webkit-scrollbar-thumb,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar-thumb,.atk-slim-scrollbar::-webkit-scrollbar-thumb:window-inactive{background:#5656564d}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:hover,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar-thumb:vertical:hover{background:#414a52c4}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:active,.atk-editor-plug-emoticons>.atk-grp-wrap::-webkit-scrollbar-thumb:vertical:active{background:#292f35c4}.atk-editor-plug-emoticons{height:100%;width:100%}.atk-editor-plug-emoticons>.atk-grp-wrap{overflow-y:scroll;overflow-x:hidden;height:100%;width:100%}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp{display:flex;flex-wrap:wrap;flex-direction:row;padding:5px 10px 35px}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp[data-type=image]>.atk-item{height:63px;width:63px}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp>.atk-item{display:flex;align-items:center;justify-content:center;padding:5px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:3px;font-size:15px;min-width:35px;margin:2px}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp>.atk-item>img{max-height:100%;width:auto}.atk-editor-plug-emoticons>.atk-grp-wrap>.atk-grp>.atk-item:hover{background:var(--at-color-bg-grey)}.atk-editor-plug-emoticons>.atk-grp-switcher{position:absolute;bottom:0;left:0;width:100%;background:var(--at-color-bg-transl);height:30px;border-top:1px solid var(--at-color-border);border-bottom:1px solid var(--at-color-border)}.atk-editor-plug-emoticons>.atk-grp-switcher>span{-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:0 10px;line-height:30px;float:left;display:block;cursor:pointer;font-size:14px}.atk-editor-plug-emoticons>.atk-grp-switcher>span:hover,.atk-editor-plug-emoticons>.atk-grp-switcher>span.active{background:var(--at-color-bg-grey)}.atk-slim-scrollbar::-webkit-scrollbar{width:4px;height:4px;background:transparent}.atk-slim-scrollbar::-webkit-scrollbar-thumb,.atk-slim-scrollbar::-webkit-scrollbar-thumb:window-inactive{background:#5656564d}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:hover{background:#414a52c4}.atk-slim-scrollbar::-webkit-scrollbar-thumb:vertical:active{background:#292f35c4}.atk-editor-plug-preview{overflow-y:scroll;overflow-x:hidden;height:100%;width:100%;padding:10px 15px} diff --git a/blog-admin/public/dist/ArtalkLite.js b/blog-admin/public/dist/ArtalkLite.js new file mode 100644 index 00000000..b32b3231 --- /dev/null +++ b/blog-admin/public/dist/ArtalkLite.js @@ -0,0 +1,11 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("marked")):"function"==typeof define&&define.amd?define(["exports","marked"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Artalk={},t.marked)}(this,(function(t,e){"use strict";var n=Object.defineProperty,i=Object.defineProperties,s=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,l=(t,e,i)=>e in t?n(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,c=(t,e)=>{for(var n in e||(e={}))r.call(e,n)&&l(t,n,e[n]);if(o)for(var n of o(e))a.call(e,n)&&l(t,n,e[n]);return t},d=(t,e)=>i(t,s(e)),h=(t,e,n)=>(l(t,"symbol"!=typeof e?e+"":e,n),n),u=(t,e,n)=>new Promise(((i,s)=>{var o=t=>{try{a(n.next(t))}catch(e){s(e)}},r=t=>{try{a(n.throw(t))}catch(e){s(e)}},a=t=>t.done?i(t.value):Promise.resolve(t.value).then(o,r);a((n=n.apply(t,e)).next())}));class p{constructor(t={}){h(this,"baseUrl","/api/v2"),h(this,"securityData",null),h(this,"securityWorker"),h(this,"abortControllers",new Map),h(this,"customFetch",((...t)=>fetch(...t))),h(this,"baseApiParams",{credentials:"same-origin",headers:{},redirect:"follow",referrerPolicy:"no-referrer"}),h(this,"setSecurityData",(t=>{this.securityData=t})),h(this,"contentFormatters",{"application/json":t=>null===t||"object"!=typeof t&&"string"!=typeof t?t:JSON.stringify(t),"text/plain":t=>null!==t&&"string"!=typeof t?JSON.stringify(t):t,"multipart/form-data":t=>Object.keys(t||{}).reduce(((e,n)=>{const i=t[n];return e.append(n,i instanceof Blob?i:"object"==typeof i&&null!==i?JSON.stringify(i):`${i}`),e}),new FormData),"application/x-www-form-urlencoded":t=>this.toQueryString(t)}),h(this,"createAbortSignal",(t=>{if(this.abortControllers.has(t)){const e=this.abortControllers.get(t);return e?e.signal:void 0}const e=new AbortController;return this.abortControllers.set(t,e),e.signal})),h(this,"abortRequest",(t=>{const e=this.abortControllers.get(t);e&&(e.abort(),this.abortControllers.delete(t))})),h(this,"request",(t=>u(this,null,(function*(){var e=t,{body:n,secure:i,path:s,type:l,query:h,format:p,baseUrl:m,cancelToken:g}=e,f=((t,e)=>{var n={};for(var i in t)r.call(t,i)&&e.indexOf(i)<0&&(n[i]=t[i]);if(null!=t&&o)for(var i of o(t))e.indexOf(i)<0&&a.call(t,i)&&(n[i]=t[i]);return n})(e,["body","secure","path","type","query","format","baseUrl","cancelToken"]);const y=("boolean"==typeof i?i:this.baseApiParams.secure)&&this.securityWorker&&(yield this.securityWorker(this.securityData))||{},v=this.mergeRequestParams(f,y),k=h&&this.toQueryString(h),$=this.contentFormatters[l||"application/json"],w=p||v.format;return this.customFetch(`${m||this.baseUrl||""}${s}${k?`?${k}`:""}`,d(c({},v),{headers:c(c({},v.headers||{}),l&&"multipart/form-data"!==l?{"Content-Type":l}:{}),signal:(g?this.createAbortSignal(g):v.signal)||null,body:null==n?null:$(n)})).then((t=>u(this,null,(function*(){const e=t;e.data=null,e.error=null;const n=w?yield t[w]().then((t=>(e.ok?e.data=t:e.error=t,e))).catch((t=>(e.error=t,e))):e;if(g&&this.abortControllers.delete(g),!t.ok)throw n;return n}))))})))),Object.assign(this,t)}encodeQueryParam(t,e){return`${encodeURIComponent(t)}=${encodeURIComponent("number"==typeof e?e:`${e}`)}`}addQueryParam(t,e){return this.encodeQueryParam(e,t[e])}addArrayQueryParam(t,e){return t[e].map((t=>this.encodeQueryParam(e,t))).join("&")}toQueryString(t){const e=t||{};return Object.keys(e).filter((t=>void 0!==e[t])).map((t=>Array.isArray(e[t])?this.addArrayQueryParam(e,t):this.addQueryParam(e,t))).join("&")}addQueryParams(t){const e=this.toQueryString(t);return e?`?${e}`:""}mergeRequestParams(t,e){return d(c(c(c({},this.baseApiParams),t),e||{}),{headers:c(c(c({},this.baseApiParams.headers||{}),t.headers||{}),e&&e.headers||{})})}} +/** + * @title Artalk API + * @version 2.0 + * @license MIT (https://github.com/ArtalkJS/Artalk/blob/master/LICENSE) + * @baseUrl /api/v2 + * @contact API Support (https://artalk.js.org) + * + * Artalk is a modern comment system based on Golang. + */let m=class extends p{constructor(){super(...arguments),h(this,"auth",{loginByEmail:(t,e={})=>this.request(c({path:"/auth/email/login",method:"POST",body:t,type:"application/json",format:"json"},e)),registerByEmail:(t,e={})=>this.request(c({path:"/auth/email/register",method:"POST",body:t,type:"application/json",format:"json"},e)),sendVerifyEmail:(t,e={})=>this.request(c({path:"/auth/email/send",method:"POST",body:t,type:"application/json",format:"json"},e)),checkDataMerge:(t={})=>this.request(c({path:"/auth/merge",method:"GET",secure:!0,format:"json"},t)),applyDataMerge:(t,e={})=>this.request(c({path:"/auth/merge",method:"POST",body:t,secure:!0,type:"application/json",format:"json"},e))}),h(this,"cache",{flushCache:(t={})=>this.request(c({path:"/cache/flush",method:"POST",secure:!0,format:"json"},t)),warmUpCache:(t={})=>this.request(c({path:"/cache/warm_up",method:"POST",secure:!0,format:"json"},t))}),h(this,"captcha",{getCaptcha:(t={})=>this.request(c({path:"/captcha",method:"GET",format:"json"},t)),getCaptchaStatus:(t={})=>this.request(c({path:"/captcha/status",method:"GET",format:"json"},t)),verifyCaptcha:(t,e={})=>this.request(c({path:"/captcha/verify",method:"POST",body:t,type:"application/json",format:"json"},e))}),h(this,"comments",{getComments:(t,e={})=>this.request(c({path:"/comments",method:"GET",query:t,secure:!0,type:"application/json",format:"json"},e)),createComment:(t,e={})=>this.request(c({path:"/comments",method:"POST",body:t,secure:!0,type:"application/json",format:"json"},e)),getComment:(t,e={})=>this.request(c({path:`/comments/${t}`,method:"GET",type:"application/json",format:"json"},e)),updateComment:(t,e,n={})=>this.request(c({path:`/comments/${t}`,method:"PUT",body:e,secure:!0,type:"application/json",format:"json"},n)),deleteComment:(t,e={})=>this.request(c({path:`/comments/${t}`,method:"DELETE",secure:!0,format:"json"},e))}),h(this,"conf",{conf:(t={})=>this.request(c({path:"/conf",method:"GET",format:"json"},t)),getSocialLoginProviders:(t={})=>this.request(c({path:"/conf/auth/providers",method:"GET",format:"json"},t)),getDomain:(t,e={})=>this.request(c({path:"/conf/domain",method:"GET",query:t,format:"json"},e))}),h(this,"notifies",{getNotifies:(t,e={})=>this.request(c({path:"/notifies",method:"GET",query:t,type:"application/json",format:"json"},e)),markAllNotifyRead:(t,e={})=>this.request(c({path:"/notifies/read",method:"POST",body:t,type:"application/json",format:"json"},e)),markNotifyRead:(t,e,n={})=>this.request(c({path:`/notifies/${t}/${e}`,method:"POST",format:"json"},n))}),h(this,"pages",{getPages:(t,e={})=>this.request(c({path:"/pages",method:"GET",query:t,secure:!0,type:"application/json",format:"json"},e)),fetchAllPages:(t,e={})=>this.request(c({path:"/pages/fetch",method:"POST",body:t,secure:!0,type:"application/json",format:"json"},e)),getPageFetchStatus:(t={})=>this.request(c({path:"/pages/fetch/status",method:"GET",secure:!0,format:"json"},t)),logPv:(t,e={})=>this.request(c({path:"/pages/pv",method:"POST",body:t,type:"application/json",format:"json"},e)),updatePage:(t,e,n={})=>this.request(c({path:`/pages/${t}`,method:"PUT",body:e,secure:!0,type:"application/json",format:"json"},n)),deletePage:(t,e={})=>this.request(c({path:`/pages/${t}`,method:"DELETE",secure:!0,format:"json"},e)),fetchPage:(t,e={})=>this.request(c({path:`/pages/${t}/fetch`,method:"POST",secure:!0,type:"application/json",format:"json"},e))}),h(this,"sendEmail",{sendEmail:(t,e={})=>this.request(c({path:"/send_email",method:"POST",body:t,secure:!0,type:"application/json",format:"json"},e))}),h(this,"settings",{getSettings:(t={})=>this.request(c({path:"/settings",method:"GET",secure:!0,format:"json"},t)),applySettings:(t,e={})=>this.request(c({path:"/settings",method:"PUT",body:t,secure:!0,type:"application/json",format:"json"},e)),getSettingsTemplate:(t,e={})=>this.request(c({path:`/settings/template/${t}`,method:"GET",secure:!0,format:"json"},e))}),h(this,"sites",{getSites:(t={})=>this.request(c({path:"/sites",method:"GET",secure:!0,format:"json"},t)),createSite:(t,e={})=>this.request(c({path:"/sites",method:"POST",body:t,secure:!0,type:"application/json",format:"json"},e)),updateSite:(t,e,n={})=>this.request(c({path:`/sites/${t}`,method:"PUT",body:e,secure:!0,type:"application/json",format:"json"},n)),deleteSite:(t,e={})=>this.request(c({path:`/sites/${t}`,method:"DELETE",secure:!0,format:"json"},e))}),h(this,"stats",{getStats:(t,e,n={})=>this.request(c({path:`/stats/${t}`,method:"GET",query:e,type:"application/json",format:"json"},n))}),h(this,"transfer",{exportArtrans:(t={})=>this.request(c({path:"/transfer/export",method:"GET",secure:!0,format:"json"},t)),importArtrans:(t,e={})=>this.request(c({path:"/transfer/import",method:"POST",body:t,secure:!0,type:"application/json"},e)),uploadArtrans:(t,e={})=>this.request(c({path:"/transfer/upload",method:"POST",body:t,secure:!0,type:"multipart/form-data",format:"json"},e))}),h(this,"upload",{upload:(t,e={})=>this.request(c({path:"/upload",method:"POST",body:t,secure:!0,type:"multipart/form-data",format:"json"},e))}),h(this,"user",{getUser:(t,e={})=>this.request(c({path:"/user",method:"GET",query:t,secure:!0,format:"json"},e)),login:(t,e={})=>this.request(c({path:"/user/access_token",method:"POST",body:t,type:"application/json",format:"json"},e)),getUserStatus:(t,e={})=>this.request(c({path:"/user/status",method:"GET",query:t,secure:!0,format:"json"},e))}),h(this,"users",{createUser:(t,e={})=>this.request(c({path:"/users",method:"POST",body:t,secure:!0,type:"application/json",format:"json"},e)),updateUser:(t,e,n={})=>this.request(c({path:`/users/${t}`,method:"PUT",body:e,secure:!0,type:"application/json",format:"json"},n)),deleteUser:(t,e={})=>this.request(c({path:`/users/${t}`,method:"DELETE",secure:!0,format:"json"},e)),getUsers:(t,e,n={})=>this.request(c({path:`/users/${t}`,method:"GET",query:e,secure:!0,type:"application/json",format:"json"},n))}),h(this,"version",{getVersion:(t={})=>this.request(c({path:"/version",method:"GET",format:"json"},t))}),h(this,"votes",{syncVotes:(t={})=>this.request(c({path:"/votes/sync",method:"POST",secure:!0,format:"json"},t)),vote:(t,e,n,i={})=>this.request(c({path:`/votes/${t}/${e}`,method:"POST",body:n,type:"application/json",format:"json"},i))})}};var g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function f(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}!function(){function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var n=0;nu(this,null,(function*(){const i=t.getApiToken&&t.getApiToken(),s=new Headers(c({Authorization:i?`Bearer ${i}`:""},null==n?void 0:n.headers));s.get("Authorization")||s.delete("Authorization");const o=yield fetch(e,d(c({},n),{headers:s}));if(!o.ok){const i=(yield o.json().catch((()=>{})))||{};let s=!1;if(t.handlers&&(yield t.handlers.get().reduce(((t,e)=>u(this,null,(function*(){yield t,!0===i[e.action]&&(yield e.handler(i),s=!0)}))),Promise.resolve())),s)return y(t,e,n);throw function(t,e){const n=new v;return n.message=e.msg||e.message||"fetch error",n.code=t,n.data=e,console.error(n),n}(o.status,i)}return o}));class v extends Error{constructor(){super(...arguments),h(this,"code",0),h(this,"message","fetch error"),h(this,"data")}}class k extends m{constructor(t){super({baseUrl:t.baseURL,customFetch:(e,n)=>y(t,e,n)}),h(this,"_opts"),this._opts=t}getUserFields(){const t=this._opts.userInfo;if((null==t?void 0:t.name)&&(null==t?void 0:t.email))return{name:t.name,email:t.email}}}var $={"&":"&","<":"<",">":">",'"':""","'":"'"},w={"&":"&","<":"<",">":">",""":'"',"'":"'"},b=/(&|<|>|"|')/g,C=/[&<>"']/g;function E(t){return $[t]}function x(t){return w[t]}function S(t){return null==t?"":String(t).replace(C,E)}function T(t){return null==t?"":String(t).replace(b,x)}S.options=T.options={};var L={encode:S,escape:S,decode:T,unescape:T,version:"1.0.0-browser"};var A=function t(e){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(e[i])?e[i]=t(e[i],n[i]):e[i]=n[i]);return e},P=function(t){return"string"==typeof t?t.toLowerCase():t};function M(t,e){return t[e]=!0,t}var O=function(t){return t.reduce(M,{})},U={uris:O(["background","base","cite","href","longdesc","src","usemap"])},R={voids:O(["area","br","col","hr","img","wbr","input","base","basefont","link","meta"])},I=L,q=P,j=R,D=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,B=/^<\s*\/\s*([\w:-]+)[^>]*>/,_=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,F=/^=0&&(e.comment&&e.comment(t.substring(4,i)),t=t.substring(i+3),n=!1):N.test(t)?r(B,l):F.test(t)&&r(D,a);var i;!function(){if(!n)return;var i,s=t.indexOf("<");s>=0?(i=t.substring(0,s),t=t.substring(s)):(i=t,t="");e.chars&&e.chars(i)}()}();var i=t===s;s=t,i&&(t="")}function r(e,i){var s=t.match(e);s&&(t=t.substring(s[0].length),s[0].replace(e,i),n=!1)}function a(t,n,s,o){var r={},a=q(n),l=j.voids[a]||!!o;s.replace(_,(function(t,e,n,i,s){r[e]=void 0===n&&void 0===i&&void 0===s?void 0:I.decode(n||i||s||"")})),l||i.push(a),e.start&&e.start(a,r,l)}function l(t,n){var s,o=0,r=q(n);if(r)for(o=i.length-1;o>=0&&i[o]!==r;o--);if(o>=0){for(s=i.length-1;s>=o;s--)e.end&&e.end(i[s]);i.length=o}}l()},Q=function(t,e){var n,i=e||{};return a(),{start:function(t,e,r){var a=H(t);if(n.ignoring)return void o(a);if(-1===(i.allowedTags||[]).indexOf(a))return void o(a);if(i.filter&&!i.filter({tag:a,attrs:e}))return void o(a);s("<"),s(a),Object.keys(e).forEach((function(t){var n=e[t],o=(i.allowedClasses||{})[a]||[],r=(i.allowedAttributes||{})[a]||[],l=H(t);("class"===l&&-1===r.indexOf(l)?(n=n.split(" ").filter((function(t){return o&&-1!==o.indexOf(t)})).join(" ").trim()).length:-1!==r.indexOf(l)&&(!0!==z.uris[l]||function(t){var e=t[0];if("#"===e||"/"===e)return!0;var n=t.indexOf(":");if(-1===n)return!0;var s=t.indexOf("?");if(-1!==s&&n>s)return!0;var o=t.indexOf("#");return-1!==o&&n>o||i.allowedSchemes.some(r);function r(e){return 0===t.indexOf(e+":")}}(n)))&&(s(" "),s(t),"string"==typeof n&&(s('="'),s(W.encode(n)),s('"')))})),s(r?"/>":">")},end:function(t){var e=H(t);-1!==(i.allowedTags||[]).indexOf(e)&&!1===n.ignoring?(s("")):r(e)},chars:function(t){!1===n.ignoring&&s(i.transformText?i.transformText(t):t)}};function s(e){t.push(e)}function o(t){V.voids[t]||(!1===n.ignoring?n={ignoring:t,depth:1}:n.ignoring===t&&n.depth++)}function r(t){n.ignoring===t&&--n.depth<=0&&a()}function a(){n={ignoring:!1,depth:0}}},Y={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 J(t,e,n){var i=[],s=!0===n?e:G({},Y,e),o=Q(i,s);return K(t,o),i.join("")}J.defaults=Y;const X=f(J),Z={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","data-src","class","loading"],code:["class"],span:["class","style"]},filter:t=>([["code",/^hljs\W+language-(.*)$/],["span",/^(hljs-.*)$/],["img",/^lazyload$/]].forEach((([e,n])=>{t.tag===e&&t.attrs.class&&!n.test(t.attrs.class)&&delete t.attrs.class})),"span"===t.tag&&t.attrs.style&&!/^color:(\W+)?#[0-9a-f]{3,6};?$/i.test(t.attrs.style)&&delete t.attrs.style,!0)};function tt(t){return X(t,Z)}var et={exports:{}};et.exports=function(){function t(t,e){return t(e={exports:{}},e.exports),e.exports}var e=t((function(t){var e=t.exports=function(){return new RegExp("(?:"+e.line().source+")|(?:"+e.block().source+")","gm")};e.line=function(){return/(?:^|\s)\/\/(.+?)$/gm},e.block=function(){return/\/\*([\S\s]*?)\*\//gm}})),n=["23AC69","91C132","F19726","E8552D","1AAB8E","E1147F","2980C1","1BA1E6","9FA0A0","F19726","E30B20","E30B20","A3338B"];function i(t){return''+t+""}return function(t,s){void 0===s&&(s={});var o=s.colors;void 0===o&&(o=n);var r=0,a={},l=new RegExp("("+/[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|\w+/.source+"|"+/'+e+"
      ";return r=++r%o.length,l}))}}();const nt=f(et.exports);function it(t){return nt(t)}function st(t){const n=new e.marked.Renderer;return n.link=ot(n,n.link),n.code=rt(),n.image=at(n,n.image,t),n}const ot=(t,e)=>(n,i,s)=>{const o=(t=>{try{return new URL(t).origin}catch(e){return""}})(n)===window.location.origin;return e.call(t,n,i,s).replace(/^(t,e)=>{const n=e||"plaintext";let i=t;return window.hljs?n&&window.hljs.getLanguage(n)&&(i=window.hljs.highlight(n,t).value):i=it(t),`
      \n${i.replace(/&/g,"&")}\n
      `},at=(t,e,{imgLazyLoad:n})=>(i,s,o)=>{const r=e.call(t,i,s,o);return n?"native"===n||!0===n?r.replace(/^${e}`)).replace(/\[(.*?)\]\((.*?)\)/g,((t,e,n)=>`
      ${e}`)).replace(/\n/g,"
      ")}(t));let i=tt(n);return ct.forEach((t=>{"function"==typeof t&&(i=t(i))})),i}function pt(...t){const e=t=>t&&"object"==typeof t&&t.constructor===Object;return t.reduce(((t,n)=>(Object.keys(null!=n?n:{}).forEach((i=>{if("__proto__"===i||"constructor"===i||"prototype"===i)return;const s=t[i],o=n[i];Array.isArray(s)&&Array.isArray(o)?t[i]=s.concat(...o):e(s)&&e(o)?t[i]=pt(s,o):t[i]=o})),t)),{})}class mt{constructor(t){h(this,"loading",!1),h(this,"listLastFetch"),h(this,"comments",[]),h(this,"notifies",[]),h(this,"page"),this.events=t}getLoading(){return this.loading}setLoading(t){this.loading=t}getListLastFetch(){return this.listLastFetch}setListLastFetch(t){this.listLastFetch=t}getComments(){return this.comments}fetchComments(t){this.events.trigger("list-fetch",t)}findComment(t){return this.comments.find((e=>e.id===t))}clearComments(){this.comments=[],this.events.trigger("list-loaded",this.comments)}loadComments(t){this.events.trigger("list-load",t),this.comments.push(...t),this.events.trigger("list-loaded",this.comments)}insertComment(t){this.comments.push(t),this.events.trigger("comment-inserted",t),this.events.trigger("list-loaded",this.comments)}updateComment(t){this.comments=this.comments.map((e=>e.id===t.id?t:e)),this.events.trigger("comment-updated",t),this.events.trigger("list-loaded",this.comments)}deleteComment(t){const e=this.comments.find((e=>e.id===t));if(!e)throw new Error(`Comment ${t} not found`);this.comments=this.comments.filter((e=>e.id!==t)),this.events.trigger("comment-deleted",e),this.events.trigger("list-loaded",this.comments)}getNotifies(){return this.notifies}updateNotifies(t){this.notifies=t,this.events.trigger("notifies-updated",this.notifies)}getPage(){return this.page}updatePage(t){this.page=t,this.events.trigger("page-loaded",t)}}function gt(t=""){const e=document.createElement("div");return e.innerHTML=t.trim(),e.firstElementChild||e}function ft(t){const e=document.createElement("div");e.innerText=t;return e.innerHTML}function yt(t){const e=RegExp(`[?&]${t}=([^&]*)`).exec(window.location.search);return e&&decodeURIComponent(e[1].replace(/\+/g," "))}function vt(t,e){const n=t=>{const e=t.getBoundingClientRect(),n=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:e.top+i,left:e.left+n}},i=n(t);if(!e)return i;const s=n(e);return{top:i.top-s.top,left:i.left-s.left}}function kt(t,e){let n=t.toString();for(;n.lengtht)){try{const n=t.getTime(),i=(new Date).getTime()-n,s=Math.floor(i/864e5);if(0===s){const t=i%864e5,n=Math.floor(t/36e5);if(0===n){const n=t%36e5,i=Math.floor(n/6e4);if(0===i){const t=n%6e4,i=Math.round(t/1e3);return i<10?e("now"):`${i} ${e("seconds")}`}return`${i} ${e("minutes")}`}return`${n} ${e("hours")}`}return s<0?e("now"):s<8?`${s} ${e("days")}`:function(t){const e=kt(t.getDate(),2),n=kt(t.getMonth()+1,2);return`${kt(t.getFullYear(),2)}-${n}-${e}`}(t)}catch(n){return console.error(n)," - "}}function wt(){return u(this,null,(function*(){const t=navigator.userAgent;if(!navigator.userAgentData||!navigator.userAgentData.getHighEntropyValues)return t;const e=navigator.userAgentData;let n=null;try{n=yield e.getHighEntropyValues(["platformVersion"])}catch(s){return console.error(s),t}const i=Number(n.platformVersion.split(".")[0]);return"Windows"===e.platform&&i>=13?t.replace(/Windows NT 10.0/,"Windows NT 11.0"):"macOS"===e.platform&&i>=11?t.replace(/(Mac OS X \d+_\d+_\d+|Mac OS X)/,`Mac OS X ${n.platformVersion.replace(/\./g,"_")}`):t}))}function bt(t){let e;try{e=new URL(t)}catch(n){return!1}return"http:"===e.protocol||"https:"===e.protocol}function Ct(t){return e=t.base,n=t.path,`${e.replace(/\/$/,"")}/${n.replace(/^\//,"")}`;var e,n}const Et={placeholder:"Leave a comment",noComment:"No Comment",send:"Send",signIn:"Sign in",signUp:"Sign up",save:"Save",nick:"Nickname",email:"Email",link:"Website",emoticon:"Emoji",preview:"Preview",uploadImage:"Upload 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:"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",noAccountPrompt:"Don't have an account?",haveAccountPrompt:"Already have an account?",forgetPassword:"Forget Password",resetPassword:"Reset Password",verificationCode:"Verification Code",verifySend:"Verify",verifyResend:"Resend",waitSeconds:"Wait {seconds}s",emailVerified:"Email has been verified",password:"Password",username:"Username",nextStep:"Next Step",skipNotVerify:"Skip, do not verify",logoutConfirm:"Are you sure to logout?",accountMergeNotice:"Your email has multiple accounts with different id.",accountMergeSelectOne:"Please select one you want to merge all the data into it.",accountMergeConfirm:"All data will be merged into one account, the id is {id}.",dismiss:"Dismiss",merge:"Merge",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 best experience!",currentVersion:"Current Version",ignore:"Ignore",open:"Open",openName:"Open {name}"},xt="ArtalkI18n",St={en:Et,"en-US":Et,"zh-CN":{placeholder:"键入内容...",noComment:"「此时无声胜有声」",send:"发送",signIn:"登录",signUp:"注册",save:"保存",nick:"昵称",email:"邮箱",link:"网址",emoticon:"表情",preview:"预览",uploadImage:"上传图片",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:"控制中心",noAccountPrompt:"没有账号?",haveAccountPrompt:"已有账号?",forgetPassword:"忘记密码",resetPassword:"重置密码",verificationCode:"验证码",verifySend:"发送验证码",verifyResend:"重新发送",waitSeconds:"等待 {seconds}秒",emailVerified:"邮箱已验证",password:"密码",username:"用户名",nextStep:"下一步",skipNotVerify:"跳过,不验证",logoutConfirm:"确定要退出登录吗?",accountMergeNotice:"您的电子邮件下有多个不同 ID 的账户。",accountMergeSelectOne:"请选择将所有数据合并到其中的一个。",accountMergeConfirm:"所有数据将合并到 ID 为 {id} 的账户中。",dismiss:"忽略",merge:"合并",frontend:"前端",backend:"后端",loading:"加载中",loadFail:"加载失败",editing:"修改中",editFail:"修改失败",deleting:"删除中",deleteFail:"删除失败",reqGot:"请求响应",reqAborted:"请求超时或意外终止",updateMsg:"请更新 Artalk {name} 以获得更好的体验!",currentVersion:"当前版本",ignore:"忽略",open:"打开",openName:"打开{name}"}};function Tt(t){return t=t.replace(/^([a-zA-Z]+)(-[a-zA-Z]+)?$/,((t,e,n)=>e.toLowerCase()+(n||"").toUpperCase())),St[t]?St[t]:window[xt]&&window[xt][t]?window[xt][t]:St.en}let Lt="en",At=Tt(Lt);function Pt(t){t!==Lt&&(Lt=t,At="string"==typeof t?Tt(t):t)}function Mt(t,e={}){let n=(null==At?void 0:At[t])||t;return n=n.replace(/\{\s*(\w+?)\s*\}/g,((t,n)=>e[n]||"")),ft(n)}class Ot{constructor(){h(this,"events",[])}on(t,e,n={}){this.events.push(c({name:t,handler:e},n))}off(t,e){e&&(this.events=this.events.filter((n=>!(n.name===t&&n.handler===e))))}trigger(t,e){this.events.slice(0).filter((e=>e.name===t&&"function"==typeof e.handler)).forEach((n=>{n.once&&this.off(t,n.handler),n.handler(e)}))}}const Ut={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:".artalk-comment-count",pvEl:".artalk-pv-count",statPageKeyAttr:"data-page-key",gravatar:{mirror:"https://www.gravatar.com/avatar/",params:"sha256=1&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:"en"};function Rt(t,e=!1){const n=e?pt(Ut,t):t;if(n.el&&"string"==typeof n.el)try{const t=document.querySelector(n.el);if(!t)throw Error(`Target element "${n.el}" was not found.`);n.el=t}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 It(t,e){return{baseURL:`${t.server}/api/v2`,siteName:t.site||"",pageKey:t.pageKey||"",pageTitle:t.pageTitle||"",timeout:t.reqTimeout,getApiToken:()=>null==e?void 0:e.get("user").getData().token,userInfo:(null==e?void 0:e.get("user").checkHasBasicUserInfo())?{name:null==e?void 0:e.get("user").getData().nick,email:null==e?void 0:e.get("user").getData().email}:void 0,handlers:null==e?void 0:e.getApiHandlers()}}function qt(t,e,n){let i=null;const s=()=>{const s=(()=>{const n=t.getConf(),i={};return e.forEach((t=>{i[t]=n[t]})),i})();var o,r;(null==i||(o=i,r=s,!(JSON.stringify(o)===JSON.stringify(r))))&&(i=s,n(s))};t.on("mounted",s),t.on("updated",s)}class jt{constructor(t){h(this,"conf"),h(this,"data"),h(this,"$root"),h(this,"events",new Ot),h(this,"mounted",!1),h(this,"apiHandlers",null),h(this,"getCommentList",this.getCommentNodes),h(this,"getCommentDataList",this.getComments),this.conf=t,this.$root=t.el,this.$root.classList.add("artalk"),this.$root.innerHTML="",this.data=new mt(this.events),this.on("mounted",(()=>{this.mounted=!0}))}inject(t,e){this[t]=e}get(t){return this[t]}getApi(){return new k(It(this.conf,this))}getApiHandlers(){return this.apiHandlers||(this.apiHandlers=function(t){const e=function(){const t=[];return{add:(e,n)=>{t.push({action:e,handler:n})},get:()=>t}}();return e.add("need_captcha",(e=>t.checkCaptcha(e))),e.add("need_login",(()=>t.checkAdmin({}))),e}(this)),this.apiHandlers}getData(){return this.data}replyComment(t,e){this.editor.setReply(t,e)}editComment(t,e){this.editor.setEditComment(t,e)}fetch(t){this.data.fetchComments(t)}reload(){this.data.fetchComments({offset:0})}listGotoFirst(){this.events.trigger("list-goto-first")}getCommentNodes(){return this.list.getCommentNodes()}getComments(){return this.data.getComments()}editorShowLoading(){this.editor.showLoading()}editorHideLoading(){this.editor.hideLoading()}editorShowNotify(t,e){this.editor.showNotify(t,e)}editorResetState(){this.editor.resetState()}showSidebar(t){this.sidebarLayer.show(t)}hideSidebar(){this.sidebarLayer.hide()}checkAdmin(t){return this.checkerLauncher.checkAdmin(t)}checkCaptcha(t){return this.checkerLauncher.checkCaptcha(t)}on(t,e){this.events.on(t,e)}off(t,e){this.events.off(t,e)}trigger(t,e){this.events.trigger(t,e)}$t(t,e={}){return Mt(t,e)}setDarkMode(t){this.updateConf({darkMode:t})}updateConf(t){this.conf=pt(this.conf,Rt(t,!1)),this.mounted&&this.events.trigger("updated",this.conf)}getConf(){return this.conf}getEl(){return this.$root}getMarked(){return ht()}watchConf(t,e){qt(this,t,e)}}function Dt(t,e){let n=t.querySelector(":scope > .atk-loading");n||(n=gt(''),(null==e?void 0:e.transparentBg)&&(n.style.background="transparent"),t.appendChild(n)),n.style.display="";const i=n.querySelector(".atk-loading-spinner");i&&(i.style.display="none",window.setTimeout((()=>{i.isConnected&&(i.style.display="")}),500))}function Bt(t){const e=t.querySelector(":scope > .atk-loading");e&&(e.style.display="none")}function _t(t,e){t?Dt(e):Bt(e)}function Ft(t,e=!0,n){let i;if(n){const e=n.getBoundingClientRect();i=t.getBoundingClientRect().top-e.top+n.scrollTop-n.clientHeight/2+t.clientHeight/2}else{const e=t.getBoundingClientRect();i=e.top+window.scrollY-(window.innerHeight/2-e.height/2)}const s={top:i,left:0,behavior:"instant"};n?n.scroll(s):window.scroll(s)}function Nt(t,e){!function(t,e,n="in"){t.classList.add(`atk-fade-${n}`);const i=()=>{t.classList.remove(`atk-fade-${n}`),t.removeEventListener("animationend",i)};t.addEventListener("animationend",i)}(t,0,"in")}function Wt(t,e,n='Artalk Error'){let i=t.querySelector(".atk-error-layer");if(null===e)return void(null!==i&&i.remove());i||(i=gt(`
      ${n}
      `),t.appendChild(i));const s=i.querySelector(".atk-error-text");s.innerHTML="",null!==e&&(e instanceof HTMLElement?s.appendChild(e):s.innerText=e)}function Ht(t){const e=gt('
      '),n=gt('');n.style.display="none",Dt(e,{transparentBg:!0}),n.src=t.getOpts().getCaptchaIframeURL(),n.onload=()=>{n.style.display="",Bt(e)},e.append(n);const i=gt('
      ');e.append(i),t.hideInteractInput();let s=!1;return function e(){return u(this,null,(function*(){var n;if(yield(n=1e3,new Promise((t=>{window.setTimeout((()=>{t(null)}),n)}))),s)return;let i=!1;try{i=(yield t.getApi().captcha.getCaptchaStatus()).data.is_pass}catch(o){i=!1}i?t.triggerSuccess():e()}))}(),i.onclick=()=>{s=!0,t.cancel()},e}const zt={request:(t,e)=>t.getApi().captcha.verifyCaptcha({value:e}),body:t=>t.get("iframe")?Ht(t):function(t){const e=gt(`${Mt("captchaCheck")}`);return e.querySelector(".atk-captcha-img").onclick=()=>{const n=e.querySelector(".atk-captcha-img");t.getApi().captcha.getCaptcha().then((t=>{n.setAttribute("src",t.data.img_data)})).catch((t=>{console.error("Failed to get captcha image ",t)}))},e}(t),onSuccess(t,e,n,i){t.set("val",n)},onError(t,e,n,i){i.querySelector(".atk-captcha-img").click(),i.querySelector('input[type="text"]').value=""}},Vt={inputType:"password",request(t,e){return u(this,null,(function*(){return(yield t.getApi().user.login({name:t.getUser().getData().nick,email:t.getUser().getData().email,password:e})).data}))},body:t=>gt(`${Mt("adminCheck")}`),onSuccess(t,e,n,i){t.getUser().update({isAdmin:!0,token:e.token}),t.getOpts().onReload()},onError(t,e,n,i){}};class Gt{constructor(t){h(this,"$el"),h(this,"$content"),h(this,"$actions"),this.$el=gt('
      \n
      \n
      \n
      \n
      \n
      '),this.$actions=this.$el.querySelector(".atk-layer-dialog-actions"),this.$content=this.$el.querySelector(".atk-layer-dialog-content"),this.$content.appendChild(t)}setYes(t){const e=gt(``);return e.onclick=this.onBtnClick(t),this.$actions.appendChild(e),this}setNo(t){const e=gt(``);return e.onclick=this.onBtnClick(t),this.$actions.appendChild(e),this}onBtnClick(t){return e=>{const n=t(e.currentTarget,this);void 0!==n&&!0!==n||this.$el.remove()}}}function Kt(t){return e=>new Promise(((n,i)=>{const s=e.onCancel;e.onCancel=()=>{s&&s(),i(new Error("user canceled the checker"))};const o=e.onSuccess;e.onSuccess=()=>{o&&o(),n()},t(e)}))}class Qt{constructor(t){h(this,"checkCaptcha",Kt((t=>{this.fire(zt,t,(e=>{e.set("img_data",t.img_data),e.set("iframe",t.iframe)}))}))),h(this,"checkAdmin",Kt((t=>{this.fire(Vt,t)}))),this.opts=t}fire(t,e,n){const i=this.opts.getCtx().get("layerManager").create(`checker-${(new Date).getTime()}`);i.show();const s=()=>{i.destroy()},o={};let r=!1;const a={set:(t,e)=>{o[t]=e},get:t=>o[t],getOpts:()=>this.opts,getUser:()=>this.opts.getCtx().get("user"),getApi:()=>this.opts.getApi(),hideInteractInput:()=>{r=!0},triggerSuccess:()=>{s(),t.onSuccess&&t.onSuccess(a,"","",l),e.onSuccess&&e.onSuccess()},cancel:()=>{s(),e.onCancel&&e.onCancel()}};n&&n(a);const l=gt();l.appendChild(t.body(a));const c=gt(``);let d;l.appendChild(c),setTimeout((()=>c.focus()),80),c.onkeyup=t=>{"Enter"!==t.key&&13!==t.keyCode||(t.preventDefault(),i.getEl().querySelector('button[data-action="confirm"]').click())};const h=new Gt(l);h.setYes((n=>{const i=c.value.trim();d||(d=n.innerText);const o=()=>{n.innerText=d||"",n.classList.remove("error")};return n.innerText=`${Mt("loading")}...`,t.request(a,i).then((n=>{s(),t.onSuccess&&t.onSuccess(a,n,i,l),e.onSuccess&&e.onSuccess()})).catch((e=>{var s;s=String(e.message||String(e)),n.innerText=s,n.classList.add("error"),t.onError&&t.onError(a,e,i,l);const r=setTimeout((()=>o()),3e3);c.onfocus=()=>{o(),clearTimeout(r)}})),!1})),h.setNo((()=>(s(),e.onCancel&&e.onCancel(),!1))),r&&(c.style.display="none",h.$el.querySelector(".atk-layer-dialog-actions").style.display="none"),i.getEl().append(h.$el),e.onMount&&e.onMount(h.$el)}}class Yt{constructor(t){h(this,"$el"),this.ctx=t}get conf(){return this.ctx.conf}getEl(){return this.$el}}const Jt={$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",$bottomLeft:".atk-bottom-left",$stateWrap:".atk-state-wrap",$plugBtnWrap:".atk-plug-btn-wrap",$plugPanelWrap:".atk-plug-panel-wrap"};class Xt{constructor(t){this.kit=t}useBtn(t="
      "){return this.$btn=gt(`${t}`),this.$btn}usePanel(t="
      "){return this.$panel=gt(t),this.$panel}useContentTransformer(t){this.contentTransformer=t}usePanelShow(t){this.kit.useEvents().on("panel-show",(e=>{e===this&&t()}))}usePanelHide(t){this.kit.useEvents().on("panel-hide",(e=>{e===this&&t()}))}useEditorStateEffect(t,e){this.editorStateEffectWhen=t,this.editorStateEffect=e}}class Zt extends Xt{constructor(){super(...arguments),h(this,"isMoved",!1)}move(t){if(this.isMoved)return;this.isMoved=!0;const e=this.kit.useUI().$el;e.after(gt('
      '));const n=gt("
      ");t.after(n),n.replaceWith(e),e.classList.add("atk-fade-in"),e.classList.add("editor-traveling")}back(){var t;this.isMoved&&(this.isMoved=!1,null==(t=this.kit.useGlobalCtx().$root.querySelector(".atk-editor-travel-placeholder"))||t.replaceWith(this.kit.useUI().$el),this.kit.useUI().$el.classList.remove("editor-traveling"))}}class te{constructor(t){h(this,"stateCurt","normal"),h(this,"stateUnmountFn",null),this.editor=t}get(){return this.stateCurt}switch(t,e){var n,i,s,o,r;if(this.stateUnmountFn&&(this.stateUnmountFn(),this.stateUnmountFn=null,null==(i=null==(n=this.editor.getPlugs())?void 0:n.get(Zt))||i.back()),"normal"!==t&&e){let n=e.$comment;this.editor.conf.flatMode||(n=n.querySelector(".atk-footer")),null==(o=null==(s=this.editor.getPlugs())?void 0:s.get(Zt))||o.move(n);const i=this.editor.ctx.conf.scrollRelativeTo&&this.editor.ctx.conf.scrollRelativeTo();Ft(this.editor.getUI().$el,!0,i);const a=null==(r=this.editor.getPlugs())?void 0:r.getPlugs().find((e=>e.editorStateEffectWhen===t));a&&a.editorStateEffect&&(this.stateUnmountFn=a.editorStateEffect(e.comment))}this.stateCurt=t}}class ee extends Yt{constructor(t){super(t),h(this,"ui"),h(this,"state"),this.ui=function(){const t=gt('
      \n
      \n \n \n \n
      \n
      \n \n
      \n \n
      \n
      \n \n \n
      \n
      \n \n
      \n
      \n
      \n
      \n'),e={$el:t};return Object.entries(Jt).forEach((([n,i])=>{e[n]=t.querySelector(i)})),e}(),this.$el=this.ui.$el,this.state=new te(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 t=this.getContentRaw();const e=this.getPlugs();return e&&(t=e.getTransformedContent(t)),t}getContentRaw(){return this.ui.$textarea.value||""}getContentMarked(){return ut(this.getContentFinal())}setContent(t){var e;this.ui.$textarea.value=t,null==(e=this.getPlugs())||e.getEvents().trigger("content-updated",t)}insertContent(t){if(document.selection)this.ui.$textarea.focus(),document.selection.createRange().text=t,this.ui.$textarea.focus();else if(this.ui.$textarea.selectionStart||0===this.ui.$textarea.selectionStart){const e=this.ui.$textarea.selectionStart,n=this.ui.$textarea.selectionEnd,i=this.ui.$textarea.scrollTop;this.setContent(this.ui.$textarea.value.substring(0,e)+t+this.ui.$textarea.value.substring(n,this.ui.$textarea.value.length)),this.ui.$textarea.focus(),this.ui.$textarea.selectionStart=e+t.length,this.ui.$textarea.selectionEnd=e+t.length,this.ui.$textarea.scrollTop=i}else this.ui.$textarea.focus(),this.ui.$textarea.value+=t}focus(){this.ui.$textarea.focus()}reset(){this.setContent(""),this.resetState()}resetState(){this.state.switch("normal")}setReply(t,e){this.state.switch("reply",{comment:t,$comment:e})}setEditComment(t,e){this.state.switch("edit",{comment:t,$comment:e})}showNotify(t,e){!function(t,e,n){const i=gt(`
      `);i.querySelector(".atk-notify-content").innerHTML=ft(e).replace("\n","
      "),t.appendChild(i);const s=()=>{i.classList.add("atk-fade-out"),setTimeout((()=>{i.remove()}),200)};let o;o=window.setTimeout((()=>{s()}),3e3),i.addEventListener("click",(()=>{s(),window.clearTimeout(o)}))}(this.ui.$notifyWrap,t,e)}showLoading(){Dt(this.ui.$el)}hideLoading(){Bt(this.ui.$el)}submit(){const t=()=>this.ctx.trigger("editor-submit");this.ctx.conf.beforeSubmit?this.ctx.conf.beforeSubmit(this,t):t()}}class ne extends Yt{constructor(t){super(t),h(this,"layer"),h(this,"$header"),h(this,"$closeBtn"),h(this,"$iframeWrap"),h(this,"$iframe"),h(this,"refreshOnShow",!0),h(this,"animTimer"),this.$el=gt('
      \n
      \n
      \n
      \n \n
      \n
      \n
      \n
      \n
      \n'),this.$header=this.$el.querySelector(".atk-sidebar-header"),this.$closeBtn=this.$header.querySelector(".atk-sidebar-close"),this.$iframeWrap=this.$el.querySelector(".atk-sidebar-iframe-wrap"),this.$closeBtn.onclick=()=>{this.hide()},this.ctx.on("user-changed",(()=>{this.refreshOnShow=!0}))}show(){return u(this,arguments,(function*(t={}){if(this.$el.style.transform="",this.initLayer(),this.layer.show(),this.refreshOnShow)this.refreshOnShow=!1,this.$iframeWrap.innerHTML="",this.$iframe=this.createIframe(t.view),this.$iframeWrap.append(this.$iframe);else{const t=this.$iframe,e=t.src;this.getDarkMode()!==e.includes("&darkMode=1")&&this.iframeLoad(t,this.getDarkMode()?e.concat("&darkMode=1"):e.replace("&darkMode=1",""))}this.authCheck({onSuccess:()=>this.show(t)}),this.animTimer=setTimeout((()=>{this.animTimer=void 0,this.$el.style.transform="translate(0, 0)",setTimeout((()=>{this.ctx.getData().updateNotifies([])}),0),this.ctx.trigger("sidebar-show")}),100)}))}hide(){var t;null==(t=this.layer)||t.hide()}authCheck(t){return u(this,null,(function*(){const e=(yield this.ctx.getApi().user.getUserStatus(c({},this.ctx.getApi().getUserFields()))).data;e.is_admin&&!e.is_login&&(this.refreshOnShow=!0,this.ctx.checkAdmin({onSuccess:()=>{setTimeout((()=>{t.onSuccess()}),500)},onCancel:()=>{this.hide()}}),this.hide())}))}initLayer(){this.layer||(this.layer=this.ctx.get("layerManager").create("sidebar",this.$el),this.layer.setOnAfterHide((()=>{this.ctx.editorResetState(),this.animTimer&&clearTimeout(this.animTimer),this.$el.style.transform="",this.ctx.trigger("sidebar-hide")})))}createIframe(t){const e=gt(''),n=Ct({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};t&&(i.view=t),this.getDarkMode()&&(i.darkMode="1");const s=new URLSearchParams(i);return this.iframeLoad(e,`${n}?${s.toString()}`),e}getDarkMode(){return"auto"===this.conf.darkMode?window.matchMedia("(prefers-color-scheme: dark)").matches:this.conf.darkMode}iframeLoad(t,e){t.src=e,Dt(this.$iframeWrap),t.onload=()=>{Bt(this.$iframeWrap)}}}const ie=t=>({import:e=>{(function(t,e="DATE_DESC",n=2){const i=[];t.filter((t=>0===t.rid)).forEach((e=>{const s={id:e.id,comment:e,children:[],level:1};s.parent=s,i.push(s),function e(i){const s=t.filter((t=>t.rid===i.id));0!==s.length&&(i.level>=n&&(i=i.parent),s.forEach((t=>{const n={id:t.id,comment:t,children:[],parent:i,level:i.level+1};i.children.push(n),e(n)})))}(s)}));const s=(n,i)=>{let s=n.id-i.id;return"DATE_ASC"===e?s=+new Date(n.comment.date)-+new Date(i.comment.date):"DATE_DESC"===e?s=+new Date(i.comment.date)-+new Date(n.comment.date):"SRC_INDEX"===e?s=t.indexOf(n.comment)-t.indexOf(i.comment):"VOTE_UP_DESC"===e&&(s=i.comment.vote_up-n.comment.vote_up),s};return function t(e){e.forEach((e=>{e.children=e.children.sort(s),t(e.children)}))}(i),i})(e,t.nestSortBy,t.nestMax).forEach((n=>{var i;const s=t.createCommentNode(n.comment);null==(i=t.$commentsWrap)||i.appendChild(s.getEl()),s.getRender().playFadeAnim();const o=(n,i)=>{i.children.forEach((i=>{const s=e.find((t=>t.id===i.comment.rid)),r=i.comment,a=t.createCommentNode(r,s);n.putChild(a),o(a,i)}))};o(s,n),s.getRender().checkHeightLimit()}))},insert:(e,n)=>{var i;const s=t.createCommentNode(e,n);if(0===e.rid)null==(i=t.$commentsWrap)||i.prepend(s.getEl());else{const n=t.findCommentNode(e.rid);n&&(n.putChild(s,"DATE_ASC"===t.nestSortBy?"append":"prepend"),s.getParents().forEach((t=>{t.getRender().heightLimitRemoveForChildren()})))}s.getRender().checkHeightLimit(),s.scrollIntoView(),s.getRender().playFadeAnim()}});function se(t,e,n,i){n.is_collapsed&&(n.is_allow_reply=!1);const s=t.createCommentNode(n,i);if(n.visible){const n=s.getEl(),i=t.$commentsWrap;"append"===e&&(null==i||i.append(n)),"prepend"===e&&(null==i||i.prepend(n)),s.getRender().playFadeAnim()}return s.getRender().checkHeightLimit(),s}class oe{constructor(t){this.options=t}getStrategy(){return this.options.flatMode?(t=this.options,{import:e=>{e.forEach((n=>{const i=0===n.rid?void 0:e.find((t=>t.id===n.rid));se(t,"append",n,i)}))},insert:(e,n)=>{se(t,"prepend",e,n).scrollIntoView()}}):ie(this.options);var t}import(t){this.getStrategy().import(t)}insert(t,e){this.getStrategy().insert(t,e)}}function re(t,e){e.forEach((({el:e,max:n,imgCheck:i})=>{if(!e)return;i&&(e.style.maxHeight=`${n+1}px`);let s=!1;const o=()=>{if(s)return;if(function(t){return parseFloat(getComputedStyle(t,null).height.replace("px",""))||0}(e)<=n)return;t.scrollable?function(t){if(!t.el)return;if(t.el.classList.contains(ce))return;t.el.classList.add(ce),t.el.style.height=`${t.max}px`}({el:e,max:n}):function(t){if(!t.el)return;if(!t.max)return;if(t.el.classList.contains(ae))return;t.el.classList.add(ae),t.el.style.height=`${t.max}px`,t.el.style.overflow="hidden";const e=gt(`
      ${Mt("readMore")}`);e.onclick=e=>{e.stopPropagation(),le(t.el),t.afterExpandBtnClick&&t.afterExpandBtnClick(e)},t.el.append(e)}({el:e,max:n,afterExpandBtnClick:()=>{var e;s=!0,null==(e=t.afterExpandBtnClick)||e.call(t)}})};if(o(),i){const t=e.querySelectorAll(".atk-content img");0===t.length&&(e.style.maxHeight=""),t.forEach((t=>{t.onload=()=>o()}))}}))}const ae="atk-height-limit";function le(t){t&&t.classList.contains(ae)&&(t.classList.remove(ae),Array.from(t.children).forEach((t=>{t.classList.contains("atk-height-limit-btn")&&t.remove()})),t.style.height="",t.style.maxHeight="",t.style.overflow="")}const ce="atk-height-limit-scroll";function de(t){if(t.$headerNick=t.$el.querySelector(".atk-nick"),t.data.link){const e=gt('');e.innerText=t.data.nick,e.href=bt(t.data.link)?t.data.link:`https://${t.data.link}`,t.$headerNick.append(e)}else t.$headerNick.innerText=t.data.nick}function he(t){t.$headerBadgeWrap=t.$el.querySelector(".atk-badge-wrap"),t.$headerBadgeWrap.innerHTML="";const e=t.data.badge_name,n=t.data.badge_color;if(e){const i=gt('');i.innerText=e.replace("管理员",Mt("admin")),i.style.backgroundColor=n||"",t.$headerBadgeWrap.append(i)}else if(t.data.is_verified){const e=gt(``);t.$headerBadgeWrap.append(e)}if(t.data.is_pinned){const e=gt(`${Mt("pin")}`);t.$headerBadgeWrap.append(e)}}function ue(t){const e=t.$el.querySelector(".atk-date");e.innerText=t.comment.getDateFormatted(),e.setAttribute("data-atk-comment-date",String(+new Date(t.data.date)))}function pe(t){if(!t.opts.uaBadge&&!t.data.ip_region)return;let e=t.$header.querySelector("atk-ua-wrap");if(e||(e=gt(''),t.$header.append(e)),e.innerHTML="",t.data.ip_region){const n=gt('');n.innerText=t.data.ip_region,e.append(n)}if(t.opts.uaBadge){const{browser:n,os:i}=t.comment.getUserUA();if(String(n).trim()){const t=gt('');t.innerText=n,e.append(t)}if(String(i).trim()){const t=gt('');t.innerText=i,e.append(t)}}}class me{constructor(t){h(this,"opts"),h(this,"$el"),h(this,"isLoading",!1),h(this,"msgRecTimer"),h(this,"msgRecTimerFunc"),h(this,"isConfirming",!1),h(this,"confirmRecTimer"),this.$el=gt(''),this.opts="object"!=typeof t?{text:t}:t,this.$el.innerText=this.getText(),this.opts.adminOnly&&this.$el.setAttribute("atk-only-admin-show","")}get isMessaging(){return!!this.msgRecTimer}appendTo(t){return t.append(this.$el),this}getText(){return"string"==typeof this.opts.text?this.opts.text:this.opts.text()}setClick(t){this.$el.onclick=e=>{if(e.stopPropagation(),!this.isLoading){if(this.opts.confirm&&!this.isMessaging){const t=()=>{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||Mt("actionConfirm"),void(this.confirmRecTimer=window.setTimeout((()=>t()),5e3));this.confirmRecTimer&&window.clearTimeout(this.confirmRecTimer),t()}if(this.msgRecTimer)return this.fireMsgRecTimer(),void this.clearMsgRecTimer();t()}}}updateText(t){t&&(this.opts.text=t),this.setLoading(!1),this.$el.innerText=this.getText()}setLoading(t,e){this.isLoading!==t&&(this.isLoading=t,t?(this.$el.classList.add("atk-btn-loading"),this.$el.innerText=e||`${Mt("loading")}...`):(this.$el.classList.remove("atk-btn-loading"),this.$el.innerText=this.getText()))}setError(t){this.setMsg(t,"atk-btn-error")}setWarn(t){this.setMsg(t,"atk-btn-warn")}setSuccess(t){this.setMsg(t,"atk-btn-success")}setMsg(t,e,n,i){this.setLoading(!1),e&&this.$el.classList.add(e),this.$el.innerText=t,this.setMsgRecTimer((()=>{this.$el.innerText=this.getText(),e&&this.$el.classList.remove(e),i&&i()}),n||2500)}setMsgRecTimer(t,e){this.fireMsgRecTimer(),this.clearMsgRecTimer(),this.msgRecTimerFunc=t,this.msgRecTimer=window.setTimeout((()=>{t(),this.clearMsgRecTimer()}),e)}fireMsgRecTimer(){this.msgRecTimerFunc&&this.msgRecTimerFunc()}clearMsgRecTimer(){this.msgRecTimer&&window.clearTimeout(this.msgRecTimer),this.msgRecTimer=void 0,this.msgRecTimerFunc=void 0}}function ge(t){t.opts.vote&&(t.voteBtnUp=new me((()=>`${Mt("voteUp")} (${t.data.vote_up||0})`)).appendTo(t.$actions),t.voteBtnUp.setClick((()=>{t.comment.getActions().vote("up")})),t.opts.voteDown&&(t.voteBtnDown=new me((()=>`${Mt("voteDown")} (${t.data.vote_down||0})`)).appendTo(t.$actions),t.voteBtnDown.setClick((()=>{t.comment.getActions().vote("down")}))))}function fe(t){if(!t.data.is_allow_reply)return;const e=gt(`${Mt("reply")}`);t.$actions.append(e),e.addEventListener("click",(e=>{e.stopPropagation(),t.opts.replyComment(t.data,t.$el)}))}function ye(t){const e=new me({text:()=>t.data.is_collapsed?Mt("expand"):Mt("collapse"),adminOnly:!0});e.appendTo(t.$actions),e.setClick((()=>{t.comment.getActions().adminEdit("collapsed",e)}))}function ve(t){const e=new me({text:()=>t.data.is_pending?Mt("pending"):Mt("approved"),adminOnly:!0});e.appendTo(t.$actions),e.setClick((()=>{t.comment.getActions().adminEdit("pending",e)}))}function ke(t){const e=new me({text:()=>t.data.is_pinned?Mt("unpin"):Mt("pin"),adminOnly:!0});e.appendTo(t.$actions),e.setClick((()=>{t.comment.getActions().adminEdit("pinned",e)}))}function $e(t){const e=new me({text:Mt("edit"),adminOnly:!0});e.appendTo(t.$actions),e.setClick((()=>{t.opts.editComment(t.data,t.$el)}))}function we(t){const e=new me({text:Mt("delete"),confirm:!0,confirmText:Mt("deleteConfirm"),adminOnly:!0});e.appendTo(t.$actions),e.setClick((()=>{t.comment.getActions().adminDelete(e)}))}const be={Avatar:function(t){const e=t.$el.querySelector(".atk-avatar"),n=gt(""),i=t.opts.avatarURLBuilder;if(n.src=i?i(t.data):t.comment.getGravatarURL(),t.data.link){const i=gt('');i.href=bt(t.data.link)?t.data.link:`https://${t.data.link}`,i.append(n),e.append(i)}else e.append(n)},Header:function(t){Object.entries({renderNick:de,renderVerifyBadge:he,renderDate:ue,renderUABadge:pe}).forEach((([e,n])=>{n(t)}))},Content:function(t){if(!t.data.is_collapsed)return t.$content.innerHTML=t.comment.getContentMarked(),void t.$content.classList.remove("atk-hide","atk-collapsed");t.$content.classList.add("atk-hide","atk-type-collapsed");const e=gt(`\n
      \n ${Mt("collapsedMsg")}\n ${Mt("expand")}\n
      `);t.$body.insertAdjacentElement("beforeend",e);const n=e.querySelector(".atk-show-btn");n.addEventListener("click",(e=>{e.stopPropagation(),t.$content.classList.contains("atk-hide")?(t.$content.innerHTML=t.comment.getContentMarked(),t.$content.classList.remove("atk-hide"),Nt(t.$content),n.innerText=Mt("collapse")):(t.$content.innerHTML="",t.$content.classList.add("atk-hide"),n.innerText=Mt("expand"))}))},ReplyAt:function(t){t.opts.flatMode||0===t.data.rid||t.opts.replyTo&&(t.$replyAt=gt(''),t.$replyAt.querySelector(".atk-nick").innerText=`${t.opts.replyTo.nick}`,t.$replyAt.onclick=()=>{t.comment.getActions().goToReplyComment()},t.$headerBadgeWrap.insertAdjacentElement("afterend",t.$replyAt))},ReplyTo:function(t){if(!t.opts.flatMode)return;if(!t.opts.replyTo)return;t.$replyTo=gt(`\n
      \n
      ${Mt("reply")} :
      \n
      \n
      `);const e=t.$replyTo.querySelector(".atk-nick");e.innerText=`@${t.opts.replyTo.nick}`,e.onclick=()=>{t.comment.getActions().goToReplyComment()};let n=ut(t.opts.replyTo.content);t.opts.replyTo.is_collapsed&&(n=`[${Mt("collapsed")}]`),t.$replyTo.querySelector(".atk-content").innerHTML=n,t.$body.prepend(t.$replyTo)},Pending:function(t){if(!t.data.is_pending)return;const e=gt(`
      ${Mt("pendingMsg")}
      `);t.$body.prepend(e)},Actions:function(t){Object.entries({renderVote:ge,renderReply:fe,renderCollapse:ye,renderModerator:ve,renderPin:ke,renderEdit:$e,renderDel:we}).forEach((([e,n])=>{n(t)}))}};class Ce{constructor(t){h(this,"comment"),h(this,"$el"),h(this,"$main"),h(this,"$header"),h(this,"$headerNick"),h(this,"$headerBadgeWrap"),h(this,"$body"),h(this,"$content"),h(this,"$childrenWrap"),h(this,"$actions"),h(this,"voteBtnUp"),h(this,"voteBtnDown"),h(this,"$replyTo"),h(this,"$replyAt"),this.comment=t}get data(){return this.comment.getData()}get opts(){return this.comment.getOpts()}render(){var t;return this.$el=gt('
      \n
      \n
      \n
      \n
      \n \n \n \n
      \n
      \n
      \n
      \n \n
      \n
      \n
      \n'),this.$main=this.$el.querySelector(".atk-main"),this.$header=this.$el.querySelector(".atk-header"),this.$body=this.$el.querySelector(".atk-body"),this.$content=this.$body.querySelector(".atk-content"),this.$actions=this.$el.querySelector(".atk-actions"),this.$el.setAttribute("id",`atk-comment-${this.data.id}`),t=this,Object.entries(be).forEach((([e,n])=>{n(t)})),this.$childrenWrap&&this.$main.append(this.$childrenWrap),this.$el}checkHeightLimit(){const t=this.opts.heightLimit;if(!t||!t.content||!t.children)return;const e=t.content,n=t.children;re({afterExpandBtnClick:()=>{const t=this.comment.getChildren();1===t.length&&le(t[0].getRender().$content)},scrollable:t.scrollable},[{el:this.$content,max:e,imgCheck:!0},{el:this.$replyTo,max:e,imgCheck:!0},{el:this.$childrenWrap,max:n,imgCheck:!1}])}heightLimitRemoveForChildren(){this.$childrenWrap&&le(this.$childrenWrap)}playFadeAnim(){Nt(this.comment.getRender().$el)}playFadeAnimForBody(){Nt(this.comment.getRender().$body)}playFlashAnim(){this.$el.classList.remove("atk-flash-once"),window.setTimeout((()=>{this.$el.classList.add("atk-flash-once")}),150)}getChildrenWrap(){return this.$childrenWrap||(this.$childrenWrap=gt('
      '),this.$main.append(this.$childrenWrap)),this.$childrenWrap}setUnread(t){t?this.$el.classList.add("atk-unread"):this.$el.classList.remove("atk-unread")}setOpenable(t){t?this.$el.classList.add("atk-openable"):this.$el.classList.remove("atk-openable")}setOpenURL(t){this.setOpenable(!0),this.$el.onclick=e=>{e.stopPropagation(),window.open(t)}}setOpenAction(t){this.setOpenable(!0),this.$el.onclick=e=>{e.stopPropagation(),t()}}}class Ee{constructor(t){h(this,"comment"),this.comment=t}get data(){return this.comment.getData()}get opts(){return this.comment.getOpts()}getApi(){return this.comment.getOpts().getApi()}vote(t){const e="up"===t?this.comment.getRender().voteBtnUp:this.comment.getRender().voteBtnDown;this.getApi().votes.vote(`comment_${t}`,this.data.id,c({},this.getApi().getUserFields())).then((t=>{var e,n;this.data.vote_up=t.data.up,this.data.vote_down=t.data.down,null==(e=this.comment.getRender().voteBtnUp)||e.updateText(),null==(n=this.comment.getRender().voteBtnDown)||n.updateText()})).catch((t=>{null==e||e.setError(Mt("voteFail")),console.error(t)}))}adminEdit(t,e){if(e.isLoading)return;e.setLoading(!0,`${Mt("editing")}...`);const n=c({},this.data);"collapsed"===t?n.is_collapsed=!n.is_collapsed:"pending"===t?n.is_pending=!n.is_pending:"pinned"===t&&(n.is_pinned=!n.is_pinned),this.getApi().comments.updateComment(this.data.id,c({},n)).then((t=>{e.setLoading(!1),this.comment.setData(t.data)})).catch((t=>{console.error(t),e.setError(Mt("editFail"))}))}adminDelete(t){t.isLoading||(t.setLoading(!0,`${Mt("deleting")}...`),this.getApi().comments.deleteComment(this.data.id).then((()=>{t.setLoading(!1),this.opts.onDelete&&this.opts.onDelete(this.comment)})).catch((e=>{console.error(e),t.setError(Mt("deleteFail"))})))}goToReplyComment(){const t=window.location.hash,e=`#atk-comment-${this.data.rid}`;window.location.hash=e,e===t&&window.dispatchEvent(new Event("hashchange"))}}class xe{constructor(t,e){h(this,"$el"),h(this,"renderInstance"),h(this,"actionInstance"),h(this,"data"),h(this,"opts"),h(this,"parent"),h(this,"children",[]),h(this,"nestCurt"),this.opts=e,this.data=c({},t),this.data.date=this.data.date.replace(/-/g,"/"),this.parent=null,this.nestCurt=1,this.actionInstance=new Ee(this),this.renderInstance=new Ce(this)}render(){const t=this.renderInstance.render();this.$el&&this.$el.replaceWith(t),this.$el=t,this.opts.onAfterRender&&this.opts.onAfterRender()}getActions(){return this.actionInstance}getRender(){return this.renderInstance}getData(){return this.data}setData(t){this.data=t,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(t,e="append"){t.parent=this,t.nestCurt=this.nestCurt+1,this.children.push(t);const n=this.getChildrenWrapEl(),i=t.getEl();"append"===e?n.append(i):"prepend"===e&&n.prepend(i),t.getRender().playFadeAnim(),t.getRender().checkHeightLimit()}getChildrenWrapEl(){return this.nestCurt>=this.opts.nestMax?this.parent.getChildrenWrapEl():this.getRender().getChildrenWrap()}getParents(){const t=[];let e=this.parent;for(;e;)t.push(e),e=e.getParent();return t}getEl(){if(!this.$el)throw new Error("comment element not initialized before `getEl()`");return this.$el}focus(){if(!this.$el)throw new Error("comment element not initialized before `focus()`");this.getParents().forEach((t=>{t.getRender().heightLimitRemoveForChildren()})),this.scrollIntoView(),this.getRender().playFlashAnim()}scrollIntoView(){this.$el&&Ft(this.$el,!1,this.opts.scrollRelativeTo&&this.opts.scrollRelativeTo())}remove(){var t;null==(t=this.$el)||t.remove()}getGravatarURL(){return`${(t={mirror:this.opts.gravatar.mirror,params:this.opts.gravatar.params,emailHash:this.data.email_encrypted}).mirror.replace(/\/$/,"")}/${t.emailHash}?${t.params.replace(/^\?/,"")}`;var t}getContentMarked(){return ut(this.data.content)}getDateFormatted(){return $t(new Date(this.data.date),Mt)}getUserUA(){const t=function(t){const e=window||{},n=navigator||{},i=String(t||n.userAgent),s={os:"",osVersion:"",engine:"",browser:"",device:"",language:"",version:""},o={Trident:i.includes("Trident")||i.includes("NET CLR"),Presto:i.includes("Presto"),WebKit:i.includes("AppleWebKit"),Gecko:i.includes("Gecko/")},r={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"):r.Chrome&&i.includes("Edg")?(r.Chrome=!1,r.Edge=!0):e.showModalDialog&&e.chrome&&(r.Chrome=!1,r[360]=!0),s.device="PC",s.language=(()=>{const t=(n.browserLanguage||n.language).split("-");return t[1]&&(t[1]=t[1].toUpperCase()),t.join("_")})();const c={engine:o,browser:r,os:a,device:l};Object.entries(c).forEach((([t,e])=>{Object.entries(e).forEach((([e,n])=>{!0===n&&(s[t]=e)}))}));const d={Windows:()=>{const t=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"}[t]||t},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:`${t.browser} ${t.version}`,os:`${t.os} ${t.osVersion}`}}getOpts(){return this.opts}}class Se{constructor(t){h(this,"opts"),h(this,"$el"),h(this,"$loading"),h(this,"$text"),h(this,"offset",0),h(this,"total",0),h(this,"origText","Load More"),this.opts=t,this.origText=this.opts.text||this.origText,this.$el=gt(``),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(t){this.$loading.style.display=t?"":"none",this.$text.style.display=t?"none":""}showErr(t){this.setLoading(!1),this.$text.innerText=t,this.$el.classList.add("atk-err"),window.setTimeout((()=>{this.$text.innerText=this.origText,this.$el.classList.remove("atk-err")}),2e3)}update(t,e){this.offset=t,this.total=e,this.checkDisabled()}checkDisabled(){this.hasMore?this.show():this.hide()}}class Te{constructor(){h(this,"instance"),h(this,"onReachedBottom",null),h(this,"opt")}create(t){return this.opt=t,this.instance=new Se({pageSize:t.pageSize,onClick:e=>u(this,null,(function*(){t.ctx.fetch({offset:e})})),text:Mt("loadMore")}),t.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(t){this.instance.setLoading(t)}update(t,e){this.instance.update(t,e)}showErr(t){this.instance.showErr(t)}next(){this.instance.click()}getHasMore(){return this.instance.hasMore}getIsClearComments(t){return 0===t.offset}dispose(){this.onReachedBottom&&this.opt.ctx.off("list-reach-bottom",this.onReachedBottom),this.instance.$el.remove()}}class Le{constructor(t,e){h(this,"opts"),h(this,"total"),h(this,"$el"),h(this,"$input"),h(this,"inputTimer"),h(this,"$prevBtn"),h(this,"$nextBtn"),h(this,"page",1),this.total=t,this.opts=e,this.$el=gt('
      \n
      \n
      \n \n
      \n \n
      \n \n
      \n
      \n
      '),this.$input=this.$el.querySelector(".atk-input"),this.$input.value=`${this.page}`,this.$input.oninput=()=>this.input(),this.$input.onkeydown=t=>this.keydown(t),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(t,e){this.page=Math.ceil(t/this.pageSize)+1,this.total=e,this.setInput(this.page),this.checkDisabled()}setInput(t){this.$input.value=`${t}`}input(t=!1){window.clearTimeout(this.inputTimer);const e=this.$input.value.trim(),n=()=>{if(""===e)return void this.setInput(this.page);let t=Number(e);Number.isNaN(t)||t<1?this.setInput(this.page):(t>this.maxPage&&(this.setInput(this.maxPage),t=this.maxPage),this.change(t))};t?n():this.inputTimer=window.setTimeout((()=>n()),800)}prev(){const t=this.page-1;t<1||this.change(t)}next(){const t=this.page+1;t>this.maxPage||this.change(t)}getHasMore(){return this.page+1<=this.maxPage}change(t){this.page=t,this.opts.onChange(this.offset),this.setInput(t),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(t){const e=t.keyCode||t.which;if(38===e){const t=Number(this.$input.value)+1;if(t>this.maxPage)return;this.setInput(t),this.input()}else if(40===e){const t=Number(this.$input.value)-1;if(t<1)return;this.setInput(t),this.input()}else 13===e&&this.input(!0)}setLoading(t){t?Dt(this.$el):Bt(this.$el)}}class Ae{constructor(){h(this,"instance")}create(t){return this.instance=new Le(t.total,{pageSize:t.pageSize,onChange:e=>u(this,null,(function*(){t.ctx.editorResetState(),t.ctx.fetch({offset:e,onSuccess:()=>{t.ctx.listGotoFirst()}})}))}),this.instance.$el}setLoading(t){this.instance.setLoading(t)}update(t,e){this.instance.update(t,e)}next(){this.instance.next()}getHasMore(){return this.instance.getHasMore()}getIsClearComments(){return!0}dispose(){this.instance.$el.remove()}}function Pe(t){const e=t.getData().getListLastFetch(),n={offset:0,total:0};return e?(n.offset=e.params.offset,e.data&&(n.total=e.params.flatMode?e.data.count:e.data.roots_count),n):n}const Me=t=>{let e=null;t.watchConf(["pagination","locale"],(n=>{const i=t.get("list");e&&e.dispose(),e=function(t){return t.pagination.readMore?new Te:new Ae}(n);const{offset:s,total:o}=Pe(t),r=e.create({ctx:t,pageSize:n.pagination.pageSize,total:o,readMoreAutoLoad:n.pagination.autoLoad});i.$commentsWrap.after(r),null==e||e.update(s,o)})),t.on("list-loaded",(n=>{const{offset:i,total:s}=Pe(t);null==e||e.update(i,s)})),t.on("list-fetch",(n=>{t.getData().getComments().length>0&&(null==e?void 0:e.getIsClearComments(n))&&t.getData().clearComments()})),t.on("list-failed",(()=>{var t;null==(t=null==e?void 0:e.showErr)||t.call(e,Mt("loadFail"))})),t.on("list-fetch",(t=>{null==e||e.setLoading(!0)})),t.on("list-fetched",(({params:t})=>{null==e||e.setLoading(!1)}))};class Oe extends Yt{constructor(t){super(t),h(this,"$commentsWrap"),h(this,"commentNodes",[]),this.$el=gt('
      \n
      \n
      \n
      \n
      \n
      \n \n \n \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n \n
      \n'),this.$commentsWrap=this.$el.querySelector(".atk-list-comments-wrap"),Me(t),this.initCrudEvents()}getCommentsWrapEl(){return this.$commentsWrap}getCommentNodes(){return this.commentNodes}getListLayout({forceFlatMode:t}={}){return new oe({$commentsWrap:this.$commentsWrap,nestSortBy:this.ctx.conf.nestSort,nestMax:this.ctx.conf.nestMax,flatMode:"boolean"==typeof t?t:this.ctx.conf.flatMode,createCommentNode:(e,n)=>{const i=function(t,e,n,i){const s=new xe(e,{onAfterRender:()=>{t.trigger("comment-rendered",s)},onDelete:e=>{t.getData().deleteComment(e.getID())},replyTo:n,flatMode:"boolean"==typeof(null==i?void 0:i.forceFlatMode)?null==i?void 0:i.forceFlatMode:t.conf.flatMode,gravatar:t.conf.gravatar,nestMax:t.conf.nestMax,heightLimit:t.conf.heightLimit,avatarURLBuilder:t.conf.avatarURLBuilder,scrollRelativeTo:t.conf.scrollRelativeTo,vote:t.conf.vote,voteDown:t.conf.voteDown,uaBadge:t.conf.uaBadge,getApi:()=>t.getApi(),replyComment:(e,n)=>t.replyComment(e,n),editComment:(e,n)=>t.editComment(e,n)});return s.render(),s}(this.ctx,e,n,{forceFlatMode:t});return this.commentNodes.push(i),i},findCommentNode:t=>this.commentNodes.find((e=>e.getID()===t))})}initCrudEvents(){this.ctx.on("list-load",(t=>{this.getListLayout().import(t)})),this.ctx.on("list-loaded",(t=>{0===t.length&&(this.commentNodes=[],this.$commentsWrap.innerHTML="")})),this.ctx.on("comment-inserted",(t=>{var e;const n=t.rid?null==(e=this.commentNodes.find((e=>e.getID()===t.rid)))?void 0:e.getData():void 0;this.getListLayout().insert(t,n)})),this.ctx.on("comment-deleted",(t=>{const e=this.commentNodes.find((e=>e.getID()===t.id));e?(e.remove(),this.commentNodes=this.commentNodes.filter((e=>e.getID()!==t.id))):console.error(`comment node id=${t.id} not found`)})),this.ctx.on("comment-updated",(t=>{const e=this.commentNodes.find((e=>e.getID()===t.id));e&&e.setData(t)}))}}let Ue,Re;function Ie(){return{init(){Ue=document.body.style.overflow,Re=document.body.style.paddingRight},unlock(){document.body.style.overflow=Ue,document.body.style.paddingRight=Re},lock(){document.body.style.overflow="hidden";const t=parseInt(window.getComputedStyle(document.body,null).getPropertyValue("padding-right"),10);document.body.style.paddingRight=`${function(){const t=document.createElement("p");t.style.width="100%",t.style.height="200px";const e=document.createElement("div");e.style.position="absolute",e.style.top="0px",e.style.left="0px",e.style.visibility="hidden",e.style.width="200px",e.style.height="150px",e.style.overflow="hidden",e.appendChild(t),document.body.appendChild(e);const n=t.offsetWidth;e.style.overflow="scroll";let i=t.offsetWidth;return n===i&&(i=e.clientWidth),document.body.removeChild(e),n-i}()+t||0}px`}}}class qe{constructor(t,e){h(this,"allowMaskClose",!0),h(this,"onAfterHide"),this.$el=t,this.opts=e}setOnAfterHide(t){this.onAfterHide=t}setAllowMaskClose(t){this.allowMaskClose=t}getAllowMaskClose(){return this.allowMaskClose}getEl(){return this.$el}show(){this.opts.onShow(),this.$el.style.display=""}hide(){return u(this,null,(function*(){this.opts.onHide(),this.$el.style.display="none",this.onAfterHide&&this.onAfterHide()}))}destroy(){return u(this,null,(function*(){this.opts.onHide(),this.$el.remove(),this.onAfterHide&&this.onAfterHide()}))}}class je{constructor(){h(this,"$wrap"),h(this,"$mask"),h(this,"items",[]),this.$wrap=gt(''),this.$mask=this.$wrap.querySelector(".atk-layer-mask")}createItem(t,e){(e=e||this.createItemElement(t)).setAttribute("data-layer-name",t),this.$wrap.appendChild(e);const n=new qe(e,{onHide:()=>this.hideWrap(e),onShow:()=>this.showWrap()});return this.getMask().addEventListener("click",(()=>{n.getAllowMaskClose()&&n.hide()})),this.items.push(n),n}createItemElement(t){const e=document.createElement("div");return e.classList.add("atk-layer-item"),e.style.display="none",this.$wrap.appendChild(e),e}getWrap(){return this.$wrap}getMask(){return this.$mask}showWrap(){this.$wrap.style.display="block",this.$mask.style.display="block",this.$mask.classList.add("atk-fade-in"),Ie().lock()}hideWrap(t){this.items.map((t=>t.getEl())).filter((e=>e!==t&&e.isConnected&&"none"!==e.style.display)).length>0||(this.$wrap.style.display="none",Ie().unlock())}}class De{constructor(t){h(this,"wrap"),this.wrap=new je,document.body.appendChild(this.wrap.getWrap()),t.on("unmounted",(()=>{this.wrap.getWrap().remove()})),Ie().init()}getEl(){return this.wrap.getWrap()}create(t,e){return this.wrap.createItem(t,e)}}const Be="ArtalkUser";class _e{constructor(t){h(this,"data"),this.opts=t;const e=JSON.parse(window.localStorage.getItem(Be)||"{}");this.data={nick:e.nick||"",email:e.email||"",link:e.link||"",token:e.token||"",isAdmin:e.isAdmin||!1}}getData(){return this.data}update(t={}){Object.entries(t).forEach((([t,e])=>{this.data[t]=e})),window.localStorage.setItem(Be,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 Fe={i18n(t){Pt(t.conf.locale),t.watchConf(["locale"],(t=>{Pt(t.locale)}))},user:t=>new _e({onUserChanged:e=>{t.trigger("user-changed",e)}}),layerManager:t=>new De(t),checkerLauncher:t=>new Qt({getCtx:()=>t,getApi:()=>t.getApi(),onReload:()=>t.reload(),getCaptchaIframeURL:()=>`${t.conf.server}/api/v2/captcha/?t=${+new Date}`}),editor(t){const e=new ee(t);return t.$root.appendChild(e.$el),e},list(t){const e=new Oe(t);return t.$root.appendChild(e.$el),e},sidebarLayer:t=>new ne(t),editorPlugs(){}};function Ne(t){return u(this,null,(function*(){yield function(t){return u(this,null,(function*(){yield We({opt:t,query:"page_comment",containers:[t.countEl,"#ArtalkCount"]})}))}(t);const e=yield function(t){return u(this,null,(function*(){if(!t.pvAdd||!t.pageKey)return;const e=(yield t.getApi().pages.logPv({page_key:t.pageKey,page_title:t.pageTitle,site_name:t.siteName})).data.pv;return{[t.pageKey]:e}}))}(t);yield function(t,e){return u(this,null,(function*(){yield We({opt:t,query:"page_pv",containers:[t.pvEl,"#ArtalkPv"],cache:e})}))}(t,e)}))}function We(t){return u(this,null,(function*(){const{opt:e}=t;let n=t.cache||{};const i=function(t){const e=new Set;return new Set(t).forEach((t=>{document.querySelectorAll(t).forEach((t=>e.add(t)))})),e}(t.containers),s=function(t,e,n,i){const s=Array.from(t).map((t=>t.getAttribute(e)||n)).filter((t=>t&&"number"!=typeof i[t]));return[...new Set(s)]}(i,e.pageKeyAttr,e.pageKey,n);if(s.length>0){const i=(yield e.getApi().stats.getStats(t.query,{page_keys:s.join(","),site_name:e.siteName})).data.data;n=c(c({},n),i)}!function(t,e,n){t.forEach((t=>{const i=t.getAttribute("data-page-key"),s=i&&e[i]||n&&e[n]||0;t.innerText=`${Number(s)}`}))}(i,n,e.pageKey)}))}const He="ArtalkContent";class ze{constructor(t){this.kit=t}reqAdd(){return u(this,null,(function*(){return(yield this.kit.useApi().comments.createComment(c({},yield this.getSubmitAddParams()))).data}))}getSubmitAddParams(){return u(this,null,(function*(){const{nick:t,email:e,link:n}=this.kit.useUser().getData(),i=this.kit.useConf();return{content:this.kit.useEditor().getContentFinal(),name:t,email:e,link:n,rid:0,page_key:i.pageKey,page_title:i.pageTitle,site_name:i.site,ua:yield wt()}}))}postSubmitAdd(t){this.kit.useGlobalCtx().getData().insertComment(t)}}class Ve extends Xt{constructor(t){super(t),h(this,"customs",[]),h(this,"defaultPreset"),this.defaultPreset=new ze(this.kit);const e=()=>this.do();this.kit.useMounted((()=>{this.kit.useGlobalCtx().on("editor-submit",e)})),this.kit.useUnmounted((()=>{this.kit.useGlobalCtx().off("editor-submit",e)}))}registerCustom(t){this.customs.push(t)}do(){return u(this,null,(function*(){if(""===this.kit.useEditor().getContentFinal().trim())return void this.kit.useEditor().focus();const t=this.customs.find((t=>t.activeCond()));this.kit.useEditor().showLoading();try{let e;(null==t?void 0:t.pre)&&t.pre(),e=(null==t?void 0:t.req)?yield t.req():yield this.defaultPreset.reqAdd(),(null==t?void 0:t.post)?t.post(e):this.defaultPreset.postSubmitAdd(e)}catch(e){return console.error(e),void this.kit.useEditor().showNotify(`${Mt("commentFail")}: ${e.message||String(e)}`,"e")}finally{this.kit.useEditor().hideLoading()}this.kit.useEditor().reset(),this.kit.useGlobalCtx().trigger("editor-submitted")}))}}class Ge extends Xt{constructor(t){super(t),h(this,"emoticons",[]),h(this,"loadingTask",null),h(this,"$grpWrap"),h(this,"$grpSwitcher"),h(this,"isListLoaded",!1),h(this,"isImgLoaded",!1),this.kit.useMounted((()=>{this.usePanel('
      '),this.useBtn(``)})),this.kit.useUnmounted((()=>{})),this.useContentTransformer((t=>this.transEmoticonImageText(t))),this.usePanelShow((()=>{(()=>{u(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 u(this,null,(function*(){this.isListLoaded||(null===this.loadingTask?(this.loadingTask=(()=>u(this,null,(function*(){Dt(this.$panel),this.emoticons=yield this.handleData(this.kit.useConf().emoticons),Bt(this.$panel),this.loadingTask=null,this.isListLoaded=!0})))(),yield this.loadingTask):yield this.loadingTask)}))}handleData(t){return u(this,null,(function*(){if(!Array.isArray(t)&&["object","string"].includes(typeof t)&&(t=[t]),!Array.isArray(t))return Wt(this.$panel,`[${Mt("emoticon")}] Data must be of Array/Object/String type`),Bt(this.$panel),[];const e=e=>{"object"==typeof e&&(e.name&&t.find((t=>t.name===e.name))||t.push(e))},n=t=>u(this,null,(function*(){yield Promise.all(t.map(((t,i)=>u(this,null,(function*(){if("object"!=typeof t||Array.isArray(t)){if(Array.isArray(t))yield n(t);else if("string"==typeof t){const i=yield this.remoteLoad(t);Array.isArray(i)?yield n(i):"object"==typeof i&&e(i)}}else e(t)})))))}));return yield n(t),t.forEach((t=>{if(this.isOwOFormat(t)){this.convertOwO(t).forEach((t=>{e(t)}))}else Array.isArray(t)&&t.forEach((t=>{e(t)}))})),t=t.filter((t=>"object"==typeof t&&!Array.isArray(t)&&!!t&&!!t.name)),this.solveNullKey(t),this.solveSameKey(t),t}))}remoteLoad(t){return u(this,null,(function*(){if(!t)return[];try{const e=yield fetch(t);return yield e.json()}catch(e){return Bt(this.$panel),console.error("[Emoticons] Load Failed:",e),Wt(this.$panel,`[${Mt("emoticon")}] ${Mt("loadFail")}: ${String(e)}`),[]}}))}solveNullKey(t){t.forEach((t=>{t.items.forEach(((e,n)=>{e.key||(e.key=`${t.name} ${n+1}`)}))}))}solveSameKey(t){const e={};t.forEach((t=>{t.items.forEach((t=>{t.key&&""!==String(t.key).trim()&&(e[t.key]?e[t.key]++:e[t.key]=1,e[t.key]>1&&(t.key=`${t.key} ${e[t.key]}`))}))}))}isOwOFormat(t){try{return"object"==typeof t&&!!Object.values(t).length&&Array.isArray(Object.keys(Object.values(t)[0].container))&&Object.keys(Object.values(t)[0].container[0]).includes("icon")}catch(e){return!1}}convertOwO(t){const e=[];return Object.entries(t).forEach((([t,n])=>{const i={name:t,type:n.type,items:[]};n.container.forEach(((e,n)=>{const s=e.icon;if(/<(img|IMG)/.test(s)){const t=/src=["'](.*?)["']/.exec(s);t&&t.length>1&&(e.icon=t[1])}i.items.push({key:e.text||`${t} ${n+1}`,val:e.icon})})),e.push(i)})),e}initEmoticonsList(){this.$grpWrap=gt('
      '),this.$panel.append(this.$grpWrap),this.emoticons.forEach(((t,e)=>{const n=gt('');this.$grpWrap.append(n),n.setAttribute("data-index",String(e)),n.setAttribute("data-grp-name",t.name),n.setAttribute("data-type",t.type),t.items.forEach((e=>{const i=gt('');if(n.append(i),e.key&&!new RegExp(`^(${t.name})?\\s?[0-9]+$`).test(e.key)&&i.setAttribute("title",e.key),"image"===t.type){const t=document.createElement("img");t.src=e.val,t.alt=e.key,i.append(t)}else i.innerText=e.val;i.onclick=()=>{"image"===t.type?this.kit.useEditor().insertContent(`:[${e.key}]`):this.kit.useEditor().insertContent(e.val||"")}}))})),this.emoticons.length>1&&(this.$grpSwitcher=gt('
      '),this.$panel.append(this.$grpSwitcher),this.emoticons.forEach(((t,e)=>{const n=gt("");n.innerText=t.name,n.setAttribute("data-index",String(e)),n.onclick=()=>this.openGrp(e),this.$grpSwitcher.append(n)}))),this.emoticons.length>0&&this.openGrp(0)}openGrp(t){var e,n,i;Array.from(this.$grpWrap.children).forEach((e=>{const n=e;n.getAttribute("data-index")!==String(t)?n.style.display="none":n.style.display=""})),null==(e=this.$grpSwitcher)||e.querySelectorAll("span.active").forEach((t=>t.classList.remove("active"))),null==(i=null==(n=this.$grpSwitcher)?void 0:n.querySelector(`span[data-index="${t}"]`))||i.classList.add("active"),this.changeListHeight()}changeListHeight(){}transEmoticonImageText(t){return this.emoticons&&Array.isArray(this.emoticons)?(this.emoticons.forEach((e=>{"image"===e.type&&Object.entries(e.items).forEach((([e,n])=>{t=t.split(`:[${n.key}]`).join(``)}))})),t):t}}const Ke=["png","jpg","jpeg","gif","bmp","svg","webp"];class Qe extends Xt{constructor(t){super(t),h(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=Ke.map((t=>`.${t}`)).join(",");const t=this.useBtn(``);t.after(this.$imgUploadInput),t.onclick=()=>{const t=this.$imgUploadInput;t.onchange=()=>{(()=>{u(this,null,(function*(){if(!t.files||0===t.files.length)return;const e=t.files[0];this.uploadImg(e)}))})()},t.click()},this.kit.useConf().imgUpload||this.$btn.setAttribute("atk-only-admin-show","")}initDragImg(){const t=t=>{if(t)for(let e=0;e{t.stopPropagation(),t.preventDefault()},n=e=>{var n;const i=null==(n=e.dataTransfer)?void 0:n.files;(null==i?void 0:i.length)&&(e.preventDefault(),t(i))},i=e=>{var n;const i=null==(n=e.clipboardData)?void 0:n.files;(null==i?void 0:i.length)&&(e.preventDefault(),t(i))};this.kit.useMounted((()=>{this.kit.useUI().$textarea.addEventListener("dragover",e),this.kit.useUI().$textarea.addEventListener("drop",n),this.kit.useUI().$textarea.addEventListener("paste",i)})),this.kit.useUnmounted((()=>{this.kit.useUI().$textarea.removeEventListener("dragover",e),this.kit.useUI().$textarea.removeEventListener("drop",n),this.kit.useUI().$textarea.removeEventListener("paste",i)}))}uploadImg(t){return u(this,null,(function*(){const e=/[^.]+$/.exec(t.name);if(!e||!Ke.includes(String(e[0]).toLowerCase()))return;if(!this.kit.useUser().checkHasBasicUserInfo())return void this.kit.useEditor().showNotify(Mt("uploadLoginMsg"),"w");let n="\n";""===this.kit.useUI().$textarea.value.trim()&&(n="");const i=`${n}![](Uploading ${t.name}...)`;let s;this.kit.useEditor().insertContent(i);try{const e=this.kit.useConf().imgUploader;s=e?{public_url:yield e(t)}:(yield this.kit.useApi().upload.upload({file:t})).data}catch(o){console.error(o),this.kit.useEditor().showNotify(`${Mt("uploadFail")}: ${o.message}`,"e")}if(s&&s.public_url){let t=s.public_url;bt(t)||(t=Ct({base:this.kit.useConf().server,path:t})),this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(i,`${n}![](${t})`))}else this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(i,""))}))}}class Ye extends Xt{constructor(t){super(t),h(this,"isPlugPanelShow",!1),this.kit.useMounted((()=>{this.usePanel('
      '),this.useBtn(``)})),this.kit.useUnmounted((()=>{})),this.kit.useEvents().on("content-updated",(t=>{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 Je=[class extends Xt{constructor(t){super(t);const e=()=>{this.save()};this.kit.useMounted((()=>{const t=window.localStorage.getItem(He)||"";""!==t.trim()&&(this.kit.useEditor().showNotify(Mt("restoredMsg"),"i"),this.kit.useEditor().setContent(t)),this.kit.useEvents().on("content-updated",e)})),this.kit.useUnmounted((()=>{this.kit.useEvents().off("content-updated",e)}))}save(){window.localStorage.setItem(He,this.kit.useEditor().getContentRaw().trim())}},class extends Xt{get $inputs(){return this.kit.useEditor().getHeaderInputEls()}constructor(t){super(t);const e={},n={},i=(t,e,n)=>()=>{this.kit.useEvents().trigger(t,{field:n,$input:e})};this.kit.useMounted((()=>{Object.entries(this.$inputs).forEach((([t,s])=>{s.addEventListener("input",e[t]=i("header-input",s,t)),s.addEventListener("change",n[t]=i("header-change",s,t))}))})),this.kit.useUnmounted((()=>{Object.entries(this.$inputs).forEach((([t,i])=>{i.removeEventListener("input",e[t]),i.removeEventListener("change",n[t])}))}))}},class extends Xt{constructor(t){super(t),h(this,"query",{timer:null,abortFn:null});const e=({$input:t,field:e})=>{"edit"!==this.kit.useEditor().getState()&&(this.kit.useUser().update({[e]:t.value.trim()}),"nick"!==e&&"email"!==e||this.fetchUserInfo())};this.kit.useMounted((()=>{Object.entries(this.kit.useEditor().getHeaderInputEls()).forEach((([t,e])=>{e.placeholder=`${Mt(t)}`,e.value=this.kit.useUser().getData()[t]||""})),this.kit.useEvents().on("header-input",e)})),this.kit.useUnmounted((()=>{this.kit.useEvents().off("header-input",e)}))}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 t=this.kit.useApi(),e="getUserCancelToken";this.query.abortFn=()=>t.abortRequest(e),t.user.getUser(c({},t.getUserFields()),{cancelToken:e}).then((t=>this.onUserInfoFetched(t.data))).catch((t=>{})).finally((()=>{this.query.abortFn=null}))}),400)}onUserInfoFetched(t){var e;t.is_login||this.kit.useUser().logout(),this.kit.useGlobalCtx().getData().updateNotifies(t.notifies),this.kit.useUser().checkHasBasicUserInfo()&&!t.is_login&&(null==(e=t.user)?void 0:e.is_admin)&&this.kit.useGlobalCtx().checkAdmin({onSuccess:()=>{}}),t.user&&t.user.link&&(this.kit.useUI().$link.value=t.user.link,this.kit.useUser().update({link:t.user.link}))}},class extends Xt{constructor(t){super(t);const e=({field:t})=>{"link"===t&&this.onLinkInputChange()};this.kit.useMounted((()=>{this.kit.useEvents().on("header-change",e)})),this.kit.useUnmounted((()=>{this.kit.useEvents().off("header-change",e)}))}onLinkInputChange(){const t=this.kit.useUI().$link.value.trim();t&&!/^(http|https):\/\//.test(t)&&(this.kit.useUI().$link.value=`https://${t}`,this.kit.useUser().update({link:this.kit.useUI().$link.value}))}},class extends Xt{constructor(t){super(t);const e=t=>this.onKeydown(t),n=()=>this.onInput();this.kit.useMounted((()=>{this.kit.useUI().$textarea.placeholder=this.kit.useConf().placeholder||Mt("placeholder"),this.kit.useUI().$textarea.addEventListener("keydown",e),this.kit.useUI().$textarea.addEventListener("input",n)})),this.kit.useUnmounted((()=>{this.kit.useUI().$textarea.removeEventListener("keydown",e),this.kit.useUI().$textarea.removeEventListener("input",n)})),this.kit.useEvents().on("content-updated",(()=>{window.setTimeout((()=>{this.adaptiveHeightByContent()}),80)}))}onKeydown(t){9===(t.keyCode||t.which)&&(t.preventDefault(),this.kit.useEditor().insertContent("\t"))}onInput(){this.kit.useEvents().trigger("content-updated",this.kit.useEditor().getContentRaw())}adaptiveHeightByContent(){const t=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+t}px`}},Ve,class extends Xt{constructor(t){super(t);const e=()=>{this.kit.useEditor().submit()};this.kit.useMounted((()=>{this.kit.useUI().$submitBtn.innerText=this.kit.useConf().sendBtn||Mt("send"),this.kit.useUI().$submitBtn.addEventListener("click",e)})),this.kit.useUnmounted((()=>{this.kit.useUI().$submitBtn.removeEventListener("click",e)}))}},Zt,class extends Xt{constructor(t){super(t),h(this,"comment"),this.useEditorStateEffect("reply",(t=>(this.setReply(t),()=>{this.cancelReply()}))),this.kit.useEvents().on("mounted",(()=>{const t=this.kit.useDeps(Ve);if(!t)throw Error("SubmitPlug not initialized");const e=new ze(this.kit);t.registerCustom({activeCond:()=>!!this.comment,req:()=>u(this,null,(function*(){if(!this.comment)throw new Error("reply comment cannot be empty");return(yield this.kit.useApi().comments.createComment(d(c({},yield e.getSubmitAddParams()),{rid:this.comment.id,page_key:this.comment.page_key,page_title:void 0,site_name:this.comment.site_name}))).data})),post:t=>{const n=this.kit.useConf();t.page_key!==n.pageKey&&window.open(`${t.page_url}#atk-comment-${t.id}`),e.postSubmitAdd(t)}})}))}setReply(t){const e=this.kit.useUI();if(!e.$sendReplyBtn){const n=gt(`${Mt("reply")} `);n.querySelector(".atk-text").innerText=`@${t.nick}`,n.addEventListener("click",(()=>{this.kit.useEditor().resetState()})),e.$stateWrap.append(n),e.$sendReplyBtn=n}this.comment=t,e.$textarea.focus()}cancelReply(){if(!this.comment)return;const t=this.kit.useUI();t.$sendReplyBtn&&(t.$sendReplyBtn.remove(),t.$sendReplyBtn=void 0),this.comment=void 0}},class extends Xt{constructor(t){super(t),h(this,"comment"),h(this,"originalSubmitBtnText","Send"),this.useEditorStateEffect("edit",(t=>(this.edit(t),()=>{this.cancelEdit()}))),this.kit.useMounted((()=>{const t=this.kit.useDeps(Ve);if(!t)throw Error("SubmitPlug not initialized");t.registerCustom({activeCond:()=>!!this.comment,req:()=>u(this,null,(function*(){const t={content:this.kit.useEditor().getContentFinal(),nick:this.kit.useUI().$nick.value,email:this.kit.useUI().$email.value,link:this.kit.useUI().$link.value},e=this.comment;return(yield this.kit.useApi().comments.updateComment(e.id,c(c({},e),t))).data})),post:t=>{this.kit.useGlobalCtx().getData().updateComment(t)}})}))}edit(t){const e=this.kit.useUI();if(!e.$editCancelBtn){const t=gt(`${Mt("editCancel")}`);t.onclick=()=>{this.kit.useEditor().resetState()},e.$stateWrap.append(t),e.$editCancelBtn=t}this.comment=t,e.$header.style.display="none",e.$nick.value=t.nick||"",e.$email.value=t.email||"",e.$link.value=t.link||"",this.kit.useEditor().setContent(t.content),e.$textarea.focus(),this.updateSubmitBtnText(Mt("save"))}cancelEdit(){if(!this.comment)return;const t=this.kit.useUI();t.$editCancelBtn&&(t.$editCancelBtn.remove(),t.$editCancelBtn=void 0),this.comment=void 0;const{nick:e,email:n,link:i}=this.kit.useUser().getData();t.$nick.value=e,t.$email.value=n,t.$link.value=i,this.kit.useEditor().setContent(""),this.restoreSubmitBtnText(),t.$header.style.display=""}updateSubmitBtnText(t){this.originalSubmitBtnText=this.kit.useUI().$submitBtn.innerText,this.kit.useUI().$submitBtn.innerText=t}restoreSubmitBtnText(){this.kit.useUI().$submitBtn.innerText=this.originalSubmitBtnText}},class extends Xt{constructor(t){super(t);const e=()=>this.open(),n=()=>this.close();this.kit.useMounted((()=>{this.kit.useEvents().on("editor-open",e),this.kit.useEvents().on("editor-close",n)})),this.kit.useUnmounted((()=>{this.kit.useEvents().off("editor-open",e),this.kit.useEvents().off("editor-close",n)}))}open(){var t;null==(t=this.kit.useUI().$textareaWrap.querySelector(".atk-comment-closed"))||t.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(gt(`
      ${Mt("onlyAdminCanReply")}
      `)),this.kit.useUser().getData().isAdmin?(this.kit.useUI().$textarea.style.display="",this.kit.useUI().$bottom.style.display=""):(this.kit.useUI().$textarea.style.display="none",this.kit.useEvents().trigger("panel-close"),this.kit.useUI().$bottom.style.display="none")}},Ge,Qe,Ye];class Xe{constructor(t){this.plugs=t}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(t){this.useEvents().on("mounted",t)}useUnmounted(t){this.useEvents().on("unmounted",t)}useDeps(t){return this.plugs.get(t)}}class Ze{constructor(t){h(this,"plugs",[]),h(this,"openedPlug",null),h(this,"events",new Ot),this.editor=t;let e=!1;this.editor.ctx.watchConf(["imgUpload","emoticons","preview","editorTravel","locale"],(t=>{e&&this.getEvents().trigger("unmounted"),this.clear(),function(t){const e=new Map;return e.set(Qe,t.imgUpload),e.set(Ge,t.emoticons),e.set(Ye,t.preview),e.set(Zt,t.editorTravel),Je.filter((t=>!e.has(t)||!!e.get(t)))}(t).forEach((t=>{const e=new Xe(this);this.plugs.push(new t(e))})),this.getEvents().trigger("mounted"),e=!0,this.loadPluginUI()})),this.events.on("panel-close",(()=>this.closePlugPanel()))}getPlugs(){return this.plugs}getEvents(){return this.events}clear(){this.plugs=[],this.events=new Ot,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((t=>this.loadPluginItem(t)))}loadPluginItem(t){const e=t.$btn;if(!e)return;this.editor.getUI().$plugBtnWrap.appendChild(e),!e.onclick&&(e.onclick=()=>{this.editor.getUI().$plugBtnWrap.querySelectorAll(".active").forEach((t=>t.classList.remove("active"))),t!==this.openedPlug?(this.openPlugPanel(t),e.classList.add("active")):this.closePlugPanel()});const n=t.$panel;n&&(n.style.display="none",this.editor.getUI().$plugPanelWrap.appendChild(n))}get(t){return this.plugs.find((e=>e instanceof t))}openPlugPanel(t){this.plugs.forEach((e=>{const n=e.$panel;n&&(e===t?(n.style.display="",this.events.trigger("panel-show",t)):(n.style.display="none",this.events.trigger("panel-hide",t)))})),this.editor.getUI().$plugPanelWrap.style.display="",this.openedPlug=t}closePlugPanel(){this.openedPlug&&(this.editor.getUI().$plugPanelWrap.style.display="none",this.events.trigger("panel-hide",this.openedPlug),this.openedPlug=null)}getTransformedContent(t){let e=t;return this.plugs.forEach((t=>{t.contentTransformer&&(e=t.contentTransformer(e))})),e}}const tn="2.8.7";function en(t){const e=gt('

      ');if(e.querySelector(".error-message").innerText=`${Mt("listLoadFailMsg")}\n${t.errMsg}`,t.retryFn){const n=gt(`${Mt("listRetry")}`);n.onclick=()=>t.retryFn&&t.retryFn(),e.appendChild(n)}if(t.onOpenSidebar){const n=gt(` | ${Mt("openName",{name:Mt("ctrlCenter")})}`);e.appendChild(n),n.onclick=()=>t.onOpenSidebar&&t.onOpenSidebar()}Wt(t.$err,e)}let nn=!1;let sn;function on(t,e){const n="atk-dark-mode";t.forEach((t=>{e?t.classList.add(n):t.classList.remove(n)}))}const rn=[t=>{t.watchConf(["imgLazyLoad","markedOptions"],(n=>{!function(t){try{if(!e.marked.name)return}catch(n){return}e.marked.setOptions(c(c({renderer:st({imgLazyLoad:t.imgLazyLoad})},dt),t.markedOptions)),lt=e.marked}({markedOptions:t.getConf().markedOptions,imgLazyLoad:t.getConf().imgLazyLoad})})),t.watchConf(["markedReplacers"],(t=>{var e;t.markedReplacers&&(e=t.markedReplacers,ct=e)}))},t=>{const e=t.get("editor"),n=new Ze(e);t.inject("editorPlugs",n)},t=>{const e=()=>{var e;e=t.get("user").getData().isAdmin,function(t){const e=[];t.$root.querySelectorAll("[atk-only-admin-show]").forEach((t=>e.push(t)));const n=document.querySelector(".atk-sidebar");return n&&n.querySelectorAll("[atk-only-admin-show]").forEach((t=>e.push(t))),e}({$root:t.$root}).forEach((t=>{e?t.classList.remove("atk-hide"):t.classList.add("atk-hide")}))};t.on("list-loaded",(()=>{e()})),t.on("user-changed",(t=>{e()}))},...[t=>{t.on("list-fetch",(e=>{if(t.getData().getLoading())return;t.getData().setLoading(!0);const n=c({offset:0,limit:t.conf.pagination.pageSize,flatMode:t.conf.flatMode,paramsModifier:t.conf.listFetchParamsModifier},e);t.getData().setListLastFetch({params:n});const i={limit:n.limit,offset:n.offset,flat_mode:n.flatMode,page_key:t.getConf().pageKey,site_name:t.getConf().site};n.paramsModifier&&n.paramsModifier(i),t.getApi().comments.getComments(c(c({},i),t.getApi().getUserFields())).then((({data:e})=>{t.getData().setListLastFetch({params:n,data:e}),t.getData().loadComments(e.comments),t.getData().updatePage(e.page),n.onSuccess&&n.onSuccess(e),t.trigger("list-fetched",{params:n,data:e})})).catch((e=>{const i={msg:e.msg||String(e),data:e.data};throw n.onError&&n.onError(i),t.trigger("list-failed",i),t.trigger("list-fetched",{params:n,error:i}),e})).finally((()=>{t.getData().setLoading(!1)}))}))},t=>{t.on("list-fetch",(e=>{const n=t.get("list");0===e.offset&&_t(!0,n.$el)})),t.on("list-fetched",(()=>{_t(!1,t.get("list").$el)}))},t=>{t.on("comment-rendered",(e=>{if(!0===t.conf.listUnreadHighlight){const n=t.getData().getNotifies(),i=n.find((t=>t.comment_id===e.getID()));i?(e.getRender().setUnread(!0),e.getRender().setOpenAction((()=>{window.open(i.read_link),t.getData().updateNotifies(n.filter((t=>t.comment_id!==e.getID())))}))):e.getRender().setUnread(!1)}})),t.on("list-goto",(e=>{const n=yt("atk_notify_key");n&&t.getApi().notifies.markNotifyRead(e,n).then((()=>{t.getData().updateNotifies(t.getData().getNotifies().filter((t=>t.comment_id!==e)))}))}))},t=>{let e;t.on("mounted",(()=>{const n=t.get("list");e=n.$el.querySelector('[data-action="admin-close-comment"]'),e.addEventListener("click",(()=>{const e=t.getData().getPage();if(!e)throw new Error("Page data not found");e.admin_only=!e.admin_only,function(t,e){t.editorShowLoading(),t.getApi().pages.updatePage(e.id,e).then((({data:e})=>{t.getData().updatePage(e)})).catch((e=>{t.editorShowNotify(`${Mt("editFail")}: ${e.message||String(e)}`,"e")})).finally((()=>{t.editorHideLoading()}))}(t,e)}))})),t.on("page-loaded",(n=>{var i,s;const o=t.get("editor");!0===(null==n?void 0:n.admin_only)?(null==(i=o.getPlugs())||i.getEvents().trigger("editor-close"),e&&(e.innerText=Mt("openComment"))):(null==(s=o.getPlugs())||s.getEvents().trigger("editor-open"),e&&(e.innerText=Mt("closeComment")))})),t.on("list-loaded",(e=>{t.editorResetState()}))},t=>{t.on("list-loaded",(()=>{(()=>{var e,n;const i=t.get("list").$el.querySelector(".atk-comment-count .atk-text");if(!i)return;const s=ft(Mt("counter",{count:`${Number(null==(n=null==(e=t.getData().getListLastFetch())?void 0:e.data)?void 0:n.count)||0}`}));i.innerHTML=s.replace(/(\d+)/,'$1')})()})),t.on("comment-inserted",(()=>{const e=t.getData().getListLastFetch();(null==e?void 0:e.data)&&(e.data.count+=1)})),t.on("comment-deleted",(()=>{const e=t.getData().getListLastFetch();(null==e?void 0:e.data)&&(e.data.count-=1)}))},t=>{let e=null;const n=()=>{if(!e)return;const n=t.get("user").getData();if(n.nick&&n.email){e.classList.remove("atk-hide");const t=e.querySelector(".atk-text");t&&(t.innerText=n.isAdmin?Mt("ctrlCenter"):Mt("msgCenter"))}else e.classList.add("atk-hide")};t.watchConf(["locale"],(i=>{const s=t.get("list");e=s.$el.querySelector('[data-action="open-sidebar"]'),e&&(e.onclick=()=>{t.showSidebar()},n())})),t.on("user-changed",(t=>{n()}))},t=>{let e=null;t.on("mounted",(()=>{const n=t.get("list");e=n.$el.querySelector(".atk-unread-badge")})),t.on("notifies-updated",(t=>{var n;n=t.length||0,e&&(n>0?(e.innerText=`${Number(n||0)}`,e.style.display="block"):e.style.display="none")}))},t=>{const e=e=>{t.conf.listFetchParamsModifier=e,t.reload()},n=t=>{!function(t){const{$dropdownWrap:e,dropdownList:n}=t;if(e.querySelector(".atk-dropdown"))return;e.classList.add("atk-dropdown-wrap"),e.append(gt(''));let i=0;const s=(t,e,n,s)=>{s(),i=t,o.querySelectorAll(".active").forEach((t=>{t.classList.remove("active")})),e.classList.add("active"),o.style.display="none",setTimeout((()=>{o.style.display=""}),80)},o=gt('
        ');n.forEach(((t,e)=>{const[n,r]=t,a=gt('
      • '),l=a.querySelector("span");l.innerText=n,l.onclick=()=>{s(e,a,n,r)},o.append(a),e===i&&a.classList.add("active")})),e.append(o)}({$dropdownWrap:t,dropdownList:[[Mt("sortLatest"),()=>{e((t=>{t.sort_by="date_desc"}))}],[Mt("sortBest"),()=>{e((t=>{t.sort_by="vote"}))}],[Mt("sortOldest"),()=>{e((t=>{t.sort_by="date_asc"}))}],[Mt("sortAuthor"),()=>{e((t=>{t.view_only_admin=!0}))}]]})};t.watchConf(["listSort","locale"],(e=>{const i=t.get("list").$el.querySelector(".atk-comment-count");i&&(e.listSort?n(i):function(t){var e,n;const{$dropdownWrap:i}=t;i.classList.remove("atk-dropdown-wrap"),null==(e=i.querySelector(".atk-arrow-down-icon"))||e.remove(),null==(n=i.querySelector(".atk-dropdown"))||n.remove()}({$dropdownWrap:i}))}))},t=>{let e=0;const n=({locker:n})=>{const i=function(){const t=window.location.hash.match(/#atk-comment-([0-9]+)/);let e=t&&t[1]&&!Number.isNaN(parseFloat(t[1]))?parseFloat(t[1]):null;e||(e=Number(yt("atk_comment")));return e||null}();i&&(n&&e===i||(e=i,t.trigger("list-goto",i)))},i=()=>n({locker:!1}),s=()=>n({locker:!0});t.on("mounted",(()=>{window.addEventListener("hashchange",i),t.on("list-loaded",s)})),t.on("unmounted",(()=>{window.removeEventListener("hashchange",i),t.off("list-loaded",s)}))},t=>{t.on("list-goto",(e=>u(this,null,(function*(){let n=t.getCommentNodes().find((t=>t.getID()===e));if(!n){const i=(yield t.getApi().comments.getComment(e)).data;t.get("list").getListLayout({forceFlatMode:!0}).insert(i.comment,i.reply_comment),n=t.getCommentNodes().find((t=>t.getID()===e))}n&&n.focus()}))))},t=>{t.on("list-loaded",(e=>{const n=t.get("list"),i=e.length<=0;let s=n.getCommentsWrapEl().querySelector(".atk-list-no-comment");i?s||(s=gt('
        '),s.innerHTML=tt(n.ctx.conf.noComment||n.ctx.$t("noComment")),n.getCommentsWrapEl().appendChild(s)):null==s||s.remove()}))},t=>{t.on("mounted",(()=>{const e=t.get("list").$el.querySelector(".atk-copyright");e&&(e.innerHTML=`Powered By Artalk`)}))},t=>{let e=null;t.on("mounted",(()=>{e=window.setInterval((()=>{t.get("list").$el.querySelectorAll("[data-atk-comment-date]").forEach((e=>{const n=e.getAttribute("data-atk-comment-date");e.innerText=$t(new Date(Number(n)),t.$t)}))}),3e4)})),t.on("unmounted",(()=>{e&&window.clearInterval(e)}))},t=>{t.on("list-fetch",(()=>{Wt(t.get("list").$el,null)})),t.on("list-failed",(e=>{en({$err:t.get("list").$el,errMsg:e.msg,errData:e.data,retryFn:()=>t.fetch({offset:0})})}))},t=>{let e=null;const n=()=>{null==e||e.disconnect(),e=null};t.on("list-loaded",(()=>{n();const i=t.get("list").getCommentsWrapEl().childNodes,s=i.length>2?i[i.length-2]:null;s&&("IntersectionObserver"in window?(i=>{const s=t.conf.scrollRelativeTo&&t.conf.scrollRelativeTo()||null;e=new IntersectionObserver((([e])=>{e.isIntersecting&&(n(),t.trigger("list-reach-bottom"))}),{threshold:.9,root:s}),e.observe(i)})(s):console.warn("IntersectionObserver api not supported"))})),t.on("unmounted",(()=>{n()}))},t=>{const e=()=>{const e=t.get("list"),n=t.conf.scrollRelativeTo&&t.conf.scrollRelativeTo();(n||window).scroll({top:vt(e.$el,n).top,left:0})};t.on("mounted",(()=>{t.on("list-goto-first",e)})),t.on("unmounted",(()=>{t.off("list-goto-first",e)}))}],t=>{t.on("list-fetch",(e=>{if(0!==e.offset)return;const n=t.getApi().getUserFields();n&&t.getApi().notifies.getNotifies(n).then((e=>{t.getData().updateNotifies(e.data.notifies)}))}))},t=>{t.watchConf(["site","pageKey","pageTitle","countEl","pvEl","statPageKeyAttr"],(e=>{Ne({getApi:()=>t.getApi(),siteName:e.site,pageKey:e.pageKey,pageTitle:e.pageTitle,countEl:e.countEl,pvEl:e.pvEl,pageKeyAttr:e.statPageKeyAttr,pvAdd:"boolean"!=typeof t.conf.pvAdd||t.conf.pvAdd})}))},t=>{t.watchConf(["apiVersion","versionCheck"],(e=>{const n=t.get("list");e.apiVersion&&e.versionCheck&&!nn&&function(t,e,n){const i=function(t,e){const n=t.split("."),i=e.split(".");for(let s=0;s<3;s++){const t=Number(n[s]),e=Number(i[s]);if(t>e)return 1;if(e>t)return-1;if(!Number.isNaN(t)&&Number.isNaN(e))return 1;if(Number.isNaN(t)&&!Number.isNaN(e))return-1}return 0}(e,n);if(0===i)return;const s=gt(`
        ${Mt("updateMsg",{name:Mt(i<0?"frontend":"backend")})} ${Mt("currentVersion")}: ${Mt("frontend")} ${e} / ${Mt("backend")} ${n}
        `),o=gt(`${Mt("ignore")}`);o.onclick=()=>{s.remove(),nn=!0},s.append(o),t.$el.parentElement.prepend(s)}(n,tn,e.apiVersion)}))},t=>{let e;const n=n=>{const i=[t.$root,t.get("layerManager").getEl()];sn||(sn=window.matchMedia("(prefers-color-scheme: dark)")),"auto"===n?(e||(e=t=>on(i,t.matches),sn.addEventListener("change",e)),on(i,sn.matches)):(e&&(sn.removeEventListener("change",e),e=void 0),on(i,n))};t.watchConf(["darkMode"],(t=>n(t.darkMode))),t.on("created",(()=>n(t.conf.darkMode))),t.on("unmounted",(()=>{e&&(null==sn||sn.removeEventListener("change",e)),e=void 0}))}],an=new Set([...rn]);function ln(t){return u(this,null,(function*(){var e;const n=new Set,i=e=>{e.forEach((e=>{"function"!=typeof e||n.has(e)||(e(t),n.add(e))}))};i(an);const{data:s}=yield t.getApi().conf.conf().catch((e=>{throw function(t,e){var n;let i="";if(null==(n=e.data)?void 0:n.err_no_site){const e={create_name:t.conf.site,create_urls:`${window.location.protocol}//${window.location.host}`};i=`sites|${JSON.stringify(e)}`}en({$err:t.get("list").$el,errMsg:e.msg||String(e),errData:e.data,retryFn:()=>ln(t),onOpenSidebar:t.get("user").getData().isAdmin?()=>t.showSidebar({view:i}):void 0})}(t,e),e}));let o={apiVersion:null==(e=s.version)?void 0:e.version};if(t.conf.useBackendConf){if(!s.frontend_conf)throw new Error("The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled");o=c(c({},o),function(t){const e=["el","pageKey","pageTitle","server","site","pvEl","countEl","statPageKeyAttr"];return Object.keys(t).forEach((n=>{e.includes(n)&&delete t[n],"darkMode"===n&&"auto"!==t[n]&&delete t[n]})),t.emoticons&&"string"==typeof t.emoticons&&(t.emoticons=t.emoticons.trim(),t.emoticons.startsWith("[")||t.emoticons.startsWith("{")?t.emoticons=JSON.parse(t.emoticons):"false"===t.emoticons&&(t.emoticons=!1)),t}(s.frontend_conf))}t.conf.remoteConfModifier&&t.conf.remoteConfModifier(o),o.pluginURLs&&(yield function(t,e){return u(this,null,(function*(){const n=new Set;if(!t||!Array.isArray(t))return n;const i=[];return t.forEach((t=>{/^(http|https):\/\//.test(t)||(t=`${e.replace(/\/$/,"")}/${t.replace(/^\//,"")}`),i.push(new Promise(((e,n)=>{if(document.querySelector(`script[src="${t}"]`))return void e();const i=document.createElement("script");i.src=t,document.head.appendChild(i),i.onload=()=>e(),i.onerror=t=>n(t)})))})),yield Promise.all(i),Object.values(window.ArtalkPlugins||{}).forEach((t=>{"function"==typeof t&&n.add(t)})),n}))}(o.pluginURLs,t.conf.server).then((t=>{i(t)})).catch((t=>{console.error("Failed to load plugin",t)}))),t.trigger("created"),t.updateConf(o),t.trigger("mounted"),t.conf.remoteConfModifier||t.fetch({offset:0})}))}class cn{constructor(t){h(this,"ctx");const e=Rt(t,!0);this.ctx=new jt(e),Object.entries(Fe).forEach((([t,e])=>{const n=e(this.ctx);n&&this.ctx.inject(t,n)})),ln(this.ctx)}getConf(){return this.ctx.getConf()}getEl(){return this.ctx.$root}update(t){return this.ctx.updateConf(t),this}reload(){this.ctx.reload()}destroy(){for(this.ctx.trigger("unmounted");this.ctx.$root.firstChild;)this.ctx.$root.removeChild(this.ctx.$root.firstChild)}on(t,e){this.ctx.on(t,e)}off(t,e){this.ctx.off(t,e)}trigger(t,e){this.ctx.trigger(t,e)}setDarkMode(t){this.ctx.setDarkMode(t)}static init(t){return new cn(t)}static use(t){an.add(t)}static loadCountWidget(t){const e=Rt(t,!0);Ne({getApi:()=>new k(It(e)),siteName:e.site,countEl:e.countEl,pvEl:e.pvEl,pageKeyAttr:e.statPageKeyAttr,pvAdd:!1})}get $root(){return this.ctx.$root}get conf(){return this.ctx.getConf()}}const dn=cn.init,hn=cn.use,un=cn.loadCountWidget;t.default=cn,t.init=dn,t.loadCountWidget=un,t.use=hn,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})); +//# sourceMappingURL=ArtalkLite.js.map diff --git a/blog-admin/public/dist/i18n/jp.js b/blog-admin/public/dist/i18n/jp.js new file mode 100644 index 00000000..2e9a128b --- /dev/null +++ b/blog-admin/public/dist/i18n/jp.js @@ -0,0 +1 @@ +!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).jp=o()}(this,(function(){"use strict";const e="ArtalkI18n";var o,n,t;return o="jp",n={placeholder:"内容を入力してください...",noComment:"コメントなし",send:"コメントを送信",signIn:"サインイン",signUp:"サインアップ",save:"コメントを保存",nick:"ニックネーム",email:"Eメール",link:"ウェブサイト",emoticon:"絵文字",preview:"プレビュー",uploadImage:"画像をアップロード",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:"コントロールセンター",noAccountPrompt:"アカウントがありませんか?",haveAccountPrompt:"アカウントをお持ちですか?",forgetPassword:"パスワードを忘れた",resetPassword:"パスワードをリセット",verificationCode:"検証コード",verifySend:"検証",verifyResend:"再送信",waitSeconds:"{seconds}秒待つ",emailVerified:"メールアドレスが確認されました",password:"パスワード",username:"ユーザー名",nextStep:"次のステップ",skipNotVerify:"スキップ、検証しない",logoutConfirm:"ログアウトしてもよろしいですか?",accountMergeNotice:"あなたのメールには異なるIDを持つ複数のアカウントがあります。",accountMergeSelectOne:"すべてのデータを統合するアカウントを選択してください。",accountMergeConfirm:"すべてのデータは1つのアカウントに統合されます。そのIDは{id}です。",dismiss:"閉じる",merge:"統合する",frontend:"フロントエンド",backend:"バックエンド",loading:"読み込み中",loadFail:"読み込みに失敗しました",editing:"編集中",editFail:"編集に失敗しました",deleting:"削除中",deleteFail:"削除に失敗しました",reqGot:"リクエストが受信されました",reqAborted:"リクエストがタイムアウトまたは予期せず中止されました",updateMsg:"Artalk {name} を更新して、より良い体験をしてください!",currentVersion:"現在のバージョン",ignore:"無視",open:"開く",openName:"{name}を開く"},t=["jp-JP"],window[e]||(window[e]={}),window[e][o]=n,t&&t.forEach((o=>{window[e][o]=n})),n})); diff --git a/blog-admin/public/dist/i18n/zh-TW.js b/blog-admin/public/dist/i18n/zh-TW.js new file mode 100644 index 00000000..4e37540a --- /dev/null +++ b/blog-admin/public/dist/i18n/zh-TW.js @@ -0,0 +1 @@ +!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self)["zh-TW"]=o()}(this,(function(){"use strict";const e="ArtalkI18n";var o,n;return o="zh-TW",n={placeholder:"輸入內容...",noComment:"「此時無聲勝有聲」",send:"發送",signIn:"登入",signUp:"註冊",save:"保存",nick:"暱稱",email:"電子郵件",link:"網址",emoticon:"表情",preview:"預覽",uploadImage:"上傳圖片",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:"控制中心",noAccountPrompt:"沒有帳號?",haveAccountPrompt:"已有帳號?",forgetPassword:"忘記密碼",resetPassword:"重置密碼",verificationCode:"驗證碼",verifySend:"發送驗證碼",verifyResend:"重新發送",waitSeconds:"等待 {seconds}秒",emailVerified:"郵箱已驗證",password:"密碼",username:"用戶名",nextStep:"下一步",skipNotVerify:"跳過,不驗證",logoutConfirm:"確定要登出嗎?",accountMergeNotice:"您的電子郵件下有多個不同 ID 的帳戶。",accountMergeSelectOne:"請選擇要將所有數據合併到其中的一個。",accountMergeConfirm:"所有數據將合併到 ID 為 {id} 的帳戶中。",dismiss:"忽略",merge:"合併",frontend:"前端",backend:"後端",loading:"加載中",loadFail:"加載失敗",editing:"修改中",editFail:"修改失敗",deleting:"刪除中",deleteFail:"刪除失敗",reqGot:"請求已接收",reqAborted:"請求超時或意外終止",updateMsg:"請更新 Artalk {name} 以獲得更好的體驗!",currentVersion:"當前版本",ignore:"忽略",open:"打開",openName:"打開{name}"},window[e]||(window[e]={}),window[e][o]=n,n})); diff --git a/blog-admin/public/dist/plugins/artalk-plugin-auth.js b/blog-admin/public/dist/plugins/artalk-plugin-auth.js new file mode 100644 index 00000000..0ab0a84e --- /dev/null +++ b/blog-admin/public/dist/plugins/artalk-plugin-auth.js @@ -0,0 +1,2 @@ +!function(){"use strict";try{if("undefined"!=typeof document){var t=document.createElement("style");t.appendChild(document.createTextNode('.atk-auth-plugin-dialog-wrap{display:flex;align-items:center;justify-content:center;flex-direction:column;height:100%}.atk-auth-plugin-dialog-wrap .atk-skip-btn{cursor:pointer;margin:10px auto 0;display:flex;justify-content:center;place-items:center;height:40px;padding:0 20px;font-size:16px;border-radius:50px;color:var(--at-color-font)}.atk-auth-plugin-dialog-wrap .atk-skip-btn:hover{opacity:.9}.atk-auth-plugin-dialog{overflow:hidden;transform:translateY(0) scale(1);animation:atkLoginDialogShowAnim .3s ease-in-out;will-change:transform,opacity,width,height;transition-property:transform,opacity,width,height;transition-duration:.2s;transition-timing-function:cubic-bezier(.25,.1,.25,1);display:flex;flex-direction:column;width:360px;max-height:500px;background:var(--at-color-bg);border-radius:18px}@keyframes atkLoginDialogShowAnim{0%{opacity:0;transform:translateY(15px) scale(1.02)}to{opacity:1;transform:translateY(0) scale(1)}}.atk-auth-plugin-dialog .atk-auth-dialog-title{display:flex;justify-content:space-between;place-items:center;padding:25px 25px 0;font-size:20px;font-weight:500;color:var(--at-color-font)}.atk-auth-plugin-dialog .atk-auth-dialog-title .atk-text{margin:0 10px}.atk-auth-plugin-dialog .atk-auth-dialog-title .atk-icon{display:flex;justify-content:center;place-items:center;height:40px;width:40px;border-radius:50%}.atk-auth-plugin-dialog .atk-auth-dialog-title .atk-icon:hover{background:var(--at-color-bg-grey)}.atk-auth-plugin-dialog .atk-view-wrap{max-height:calc(100% - 65px);overflow-y:auto}.atk-auth-plugin-dialog .atk-methods-page .atk-methods{padding:12px 20px 20px}.atk-auth-plugin-dialog .atk-methods-page .atk-methods .atk-method-item{display:flex;align-items:center;padding:15px 25px;cursor:pointer;border-radius:10px}.atk-auth-plugin-dialog .atk-methods-page .atk-methods .atk-method-item:hover{background:var(--at-color-bg-grey)}.atk-auth-plugin-dialog .atk-methods-page .atk-methods .atk-method-item .atk-method-icon{width:40px;height:40px;margin-right:20px;background-repeat:no-repeat;background-size:contain;background-position:center}.atk-auth-plugin-dialog .atk-methods-page .atk-methods .atk-method-item .atk-method-text{font-size:16px;font-weight:500;color:var(--at-color-font)}.atk-auth-plugin-dialog .atk-form{padding:20px 30px}.atk-auth-plugin-dialog .atk-form .atk-form-bottom{padding:5px 0;text-align:center;font-size:14px}.atk-auth-plugin-dialog .atk-form .atk-form-bottom .atk-link{cursor:pointer;text-align:center;color:var(--at-color-main)}.atk-auth-plugin-dialog .atk-form .atk-form-bottom .atk-link:hover{text-decoration:underline}.atk-auth-plugin-dialog .atk-form input{width:100%;padding:10px 20px;margin:5px 0;font-size:16px;border-radius:10px;border:1px solid var(--at-color-bg-grey);background:var(--at-color-bg-grey);color:var(--at-color-font);transition:border-color .2s;outline:none}.atk-auth-plugin-dialog .atk-form input:focus{border-color:var(--at-color-primary)}.atk-auth-plugin-dialog .atk-form button[type=submit]{width:100%;padding:10px 20px;margin:10px 0;font-size:16px;border-radius:10px;background:var(--at-color-main);color:var(--at-color-bg);cursor:pointer;transition:background .2s;border:0}.atk-auth-plugin-dialog .atk-form button[type=submit]:hover{opacity:.9}.atk-auth-plugin-dialog .atk-form .atk-input-grp{position:relative}.atk-auth-plugin-dialog .atk-form .atk-input-grp>input{padding-right:115px}.atk-auth-plugin-dialog .atk-form .atk-input-grp-btn{position:absolute;right:0;top:50%;transform:translateY(-50%);padding:10px 15px;font-size:14px;color:var(--at-color-main);cursor:pointer}.atk-auth-plugin-dialog[data-dialog-name=merge]{background-size:100% auto;background-position:center top;background-repeat:no-repeat;background-image:url(\'data:image/svg+xml,\')}.atk-auth-plugin-dialog[data-dialog-name=merge] .atk-auth-dialog-title{padding-top:50px;color:#361e6a}.atk-auth-plugin-dialog[data-dialog-name=merge] .atk-text:first-of-type{color:#472a84}.atk-auth-plugin-dialog .atk-merge-confirm-page{padding:15px 35px 30px}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-text{font-size:16px;color:var(--at-color-font);margin-bottom:20px}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-usernames{display:flex;flex-direction:column;color:var(--at-color-font);margin-bottom:20px}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-usernames .atk-item{border-radius:10px;padding:10px 15px;margin:5px 0;display:flex;justify-content:space-between;place-items:center;cursor:pointer;border:1px solid var(--at-color-border)}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-usernames .atk-item.active{background:var(--at-color-bg-grey)}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-usernames .atk-item .atk-username{flex:auto;text-align:center}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-dialog-footer{display:flex;justify-content:space-between;place-items:center;margin-top:20px}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-dialog-footer .atk-btn{padding:10px 20px;font-size:16px;border-radius:10px;cursor:pointer}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-dialog-footer .atk-btn:hover{opacity:.9}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-dialog-footer .atk-btn.atk-btn-no{background:var(--at-color-bg-grey);color:var(--at-color-font)}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-dialog-footer .atk-btn.atk-btn-yes{background:var(--at-color-main);color:var(--at-color-bg)}.atk-auth-plugin-dialog .atk-merge-confirm-page .atk-dialog-footer .atk-btn.atk-btn-yes.disabled{opacity:.5;cursor:not-allowed}.atk-main-editor .atk-editor-user-wrap{margin-top:10px}.atk-main-editor .atk-editor-user-wrap .atk-editor-user{display:inline-flex;flex-direction:row;place-items:center;cursor:pointer;border-radius:3px;padding:0 10px}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-user-btn{display:flex;place-items:center;justify-content:center;padding:5px;border-radius:3px}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-user-btn:hover{background:var(--at-color-bg-grey-transl)}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-user-btn:not(:last-child){margin-right:5px}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-user-profile-btn{padding-left:12px;padding-right:12px}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-name{color:var(--at-color-font)}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-avatar{width:20px;height:20px;border-radius:50%;margin-right:15px;background-position:center;background-size:cover;background-color:#d5d5d5}.atk-main-editor .atk-editor-user-wrap .atk-editor-user .atk-logout{height:100%;color:var(--at-color-font);font-size:1.3em;display:flex;place-items:center;justify-content:center}')),document.head.appendChild(t)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}}(); +!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-plugin-auth"]=e["artalk-plugin-auth"]||{})}(this,(function(e){"use strict";var t,n=Object.defineProperty,r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,i=(e,t,r)=>t in e?n(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,s=(e,t)=>{var n={};for(var i in e)o.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i]);if(null!=e&&r)for(var i of r(e))t.indexOf(i)<0&&l.call(e,i)&&(n[i]=e[i]);return n},a=(e,t,n)=>new Promise(((r,o)=>{var l=e=>{try{s(n.next(e))}catch(t){o(t)}},i=e=>{try{s(n.throw(e))}catch(t){o(t)}},s=e=>e.done?r(e.value):Promise.resolve(e.value).then(l,i);s((n=n.apply(e,t)).next())}));const c=Symbol("solid-proxy"),u=Symbol("solid-track"),d={equals:(e,t)=>e===t};let f=N;const g=1,p=2,h={owned:null,cleanups:null,context:null,owner:null},v={};var m=null;let y=null,b=null,k=null,w=null,$=0;function A(e,t){const n=b,r=m,o=0===e.length,l=void 0===t?r:t,i=o?h:{owned:null,cleanups:null,context:l?l.context:null,owner:l},s=o?e:()=>e((()=>B((()=>K(i)))));m=i,b=null;try{return M(s,!0)}finally{b=n,m=r}}function x(e,t){const n={value:e,observers:null,observerSlots:null,comparator:(t=t?Object.assign({},d,t):d).equals||void 0};return[_.bind(n),e=>("function"==typeof e&&(e=e(n.value)),L(n,e))]}function C(e,t,n){D(I(e,t,!0,g))}function S(e,t,n){D(I(e,t,!1,g))}function O(e,t,n){f=H;const r=I(e,t,!1,g);r.user=!0,w?w.push(r):D(r)}function P(e,t,n){n=n?Object.assign({},d,n):d;const r=I(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,D(r),_.bind(r)}function j(e,t,n){let r,o,l;2===arguments.length&&"object"==typeof t||1===arguments.length?(r=!0,o=e,l={}):(r=e,o=t,l={});let i=null,s=v,a=!1,c="initialValue"in l,u="function"==typeof r&&P(r);const d=new Set,[f,g]=(l.storage||x)(l.initialValue),[p,h]=x(void 0),[m,y]=x(void 0,{equals:!1}),[k,w]=x(c?"ready":"unresolved");function $(e,t,n,r){return i===e&&(i=null,void 0!==r&&(c=!0),e!==s&&t!==s||!l.onHydrated||queueMicrotask((()=>l.onHydrated(r,{value:t}))),s=v,function(e,t){M((()=>{void 0===t&&g((()=>e)),w(void 0!==t?"errored":c?"ready":"unresolved"),h(t);for(const e of d.keys())e.decrement();d.clear()}),!1)}(t,n)),t}function A(){const e=undefined,t=f(),n=p();if(void 0!==n&&!i)throw n;return b&&!b.user&&e&&C((()=>{m(),i&&(e.resolved||d.has(e)||(e.increment(),d.add(e)))})),t}function S(e=!0){if(!1!==e&&a)return;a=!1;const t=u?u():r;if(null==t||!1===t)return void $(i,B(f));const n=s!==v?s:B((()=>o(t,{value:f(),refetching:e})));return(l=n)&&"object"==typeof l&&"then"in l?(i=n,"value"in n?("success"===n.status?$(i,n.value,void 0,t):$(i,void 0,void 0,t),n):(a=!0,queueMicrotask((()=>a=!1)),M((()=>{w(c?"refreshing":"pending"),y()}),!1),n.then((e=>$(n,e,void 0,t)),(e=>$(n,void 0,R(e),t))))):($(i,n,void 0,t),n);var l}return Object.defineProperties(A,{state:{get:()=>k()},error:{get:()=>p()},loading:{get(){const e=k();return"pending"===e||"refreshing"===e}},latest:{get(){if(!c)return A();const e=p();if(e&&!i)throw e;return f()}}}),u?C((()=>S(!1))):S(!1),[A,{refetch:S,mutate:g}]}function B(e){if(null===b)return e();const t=b;b=null;try{return e()}finally{b=t}}function T(e){return null===m||(null===m.cleanups?m.cleanups=[e]:m.cleanups.push(e)),e}function E(){return b}function _(){if(this.sources&&this.state)if(this.state===g)D(this);else{const e=k;k=null,M((()=>V(this)),!1),k=e}if(b){const e=this.observers?this.observers.length:0;b.sources?(b.sources.push(this),b.sourceSlots.push(e)):(b.sources=[this],b.sourceSlots=[e]),this.observers?(this.observers.push(b),this.observerSlots.push(b.sources.length-1)):(this.observers=[b],this.observerSlots=[b.sources.length-1])}return this.value}function L(e,t,n){let r=e.value;return e.comparator&&e.comparator(r,t)||(e.value=t,e.observers&&e.observers.length&&M((()=>{for(let t=0;t1e6)throw k=[],new Error}),!1)),t}function D(e){if(!e.fn)return;K(e);const t=$;!function(e,t,n){let r;const o=m,l=b;b=m=e;try{r=e.fn(t)}catch(i){return e.pure&&(e.state=g,e.owned&&e.owned.forEach(K),e.owned=null),e.updatedAt=n+1,z(i)}finally{b=l,m=o}(!e.updatedAt||e.updatedAt<=n)&&(null!=e.updatedAt&&"observers"in e?L(e,r):e.value=r,e.updatedAt=n)}(e,e.value,t)}function I(e,t,n,r=g,o){const l={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:m,context:m?m.context:null,pure:n};return null===m||m!==h&&(m.owned?m.owned.push(l):m.owned=[l]),l}function q(e){if(0===e.state)return;if(e.state===p)return V(e);if(e.suspense&&B(e.suspense.inFallback))return e.suspense.effects.push(e);const t=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<$);)e.state&&t.push(e);for(let n=t.length-1;n>=0;n--)if((e=t[n]).state===g)D(e);else if(e.state===p){const n=k;k=null,M((()=>V(e,t[0])),!1),k=n}}function M(e,t){if(k)return e();let n=!1;t||(k=[]),w?n=!0:w=[],$++;try{const t=e();return function(e){k&&(N(k),k=null);if(e)return;const t=w;w=null,t.length&&M((()=>f(t)),!1)}(n),t}catch(r){n||(w=null),k=null,z(r)}}function N(e){for(let t=0;t=0;t--)K(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}e.state=0}function R(e){return e instanceof Error?e:new Error("string"==typeof e?e:"Unknown error",{cause:e})}function z(e,t=m){throw R(e)}const F=Symbol("fallback");function G(e){for(let t=0;te(t||{})))}function Z(e){const t="fallback"in e&&{fallback:()=>e.fallback};return P(function(e,t,n={}){let r=[],o=[],l=[],i=0,s=t.length>1?[]:null;return T((()=>G(l))),()=>{let a,c,d=e()||[];return d[u],B((()=>{let e,t,u,g,p,h,v,m,y,b=d.length;if(0===b)0!==i&&(G(l),l=[],r=[],o=[],i=0,s&&(s=[])),n.fallback&&(r=[F],o[0]=A((e=>(l[0]=e,n.fallback()))),i=1);else if(0===i){for(o=new Array(b),c=0;c=h&&m>=h&&r[v]===d[m];v--,m--)u[m]=o[v],g[m]=l[v],s&&(p[m]=s[v]);for(e=new Map,t=new Array(m+1),c=m;c>=h;c--)y=d[c],a=e.get(y),t[c]=void 0===a?-1:a,e.set(y,c);for(a=h;a<=v;a++)y=r[a],c=e.get(y),void 0!==c&&-1!==c?(u[c]=o[a],g[c]=l[a],s&&(p[c]=s[a]),c=t[c],e.set(y,c)):l[a]();for(c=h;ce.each),e.children,t||void 0))}function W(e){const t=e.keyed,n=P((()=>e.when),void 0,{equals:(e,n)=>t?e===n:!e==!n});return P((()=>{const r=n();if(r){const o=e.children;return"function"==typeof o&&o.length>0?B((()=>o(t?r:()=>{if(!B(n))throw`Stale read from <${"Show"}>.`;return e.when}))):o}return e.fallback}),void 0,void 0)}const X="_$DX_DELEGATE";function J(e,t,n,r={}){let o;return A((r=>{o=r,t===document?e():re(t,e(),t.firstChild?null:void 0,n)}),r.owner),()=>{o(),t.textContent=""}}function Q(e,t,n){let r;const o=()=>(r||(r=(()=>{const t=document.createElement("template");return t.innerHTML=e,t.content.firstChild})())).cloneNode(!0);return o.cloneNode=o,o}function ee(e,t=window.document){const n=t[X]||(t[X]=new Set);for(let r=0,o=e.length;rle(e,t(),r,n)),r)}function oe(e){const t=`$$${e.type}`;let n=e.composedPath&&e.composedPath()[0]||e.target;for(e.target!==n&&Object.defineProperty(e,"target",{configurable:!0,value:n}),Object.defineProperty(e,"currentTarget",{configurable:!0,get:()=>n||document});n;){const r=n[t];if(r&&!n.disabled){const o=n[`${t}Data`];if(void 0!==o?r.call(n,o,e):r.call(n,e),e.cancelBubble)return}n=n._$host||n.parentNode||n.host}}function le(e,t,n,r,o){for(;"function"==typeof n;)n=n();if(t===n)return n;const l=typeof t,i=void 0!==r;if(e=i&&n[0]&&n[0].parentNode||e,"string"===l||"number"===l)if("number"===l&&(t=t.toString()),i){let o=n[0];o&&3===o.nodeType?o.data!==t&&(o.data=t):o=document.createTextNode(t),n=ae(e,n,r,o)}else n=""!==n&&"string"==typeof n?e.firstChild.data=t:e.textContent=t;else if(null==t||"boolean"===l)n=ae(e,n,r);else{if("function"===l)return S((()=>{let o=t();for(;"function"==typeof o;)o=o();n=le(e,o,n,r)})),()=>n;if(Array.isArray(t)){const l=[],s=n&&Array.isArray(n);if(ie(l,t,n,o))return S((()=>n=le(e,l,n,r,!0))),()=>n;if(0===l.length){if(n=ae(e,n,r),i)return n}else s?0===n.length?se(e,l,r):function(e,t,n){let r=n.length,o=t.length,l=r,i=0,s=0,a=t[o-1].nextSibling,c=null;for(;ir-s){const o=t[i];for(;s=0;l--){const i=t[l];if(o!==i){const t=i.parentNode===e;r||l?t&&i.remove():t?e.replaceChild(o,i):e.insertBefore(o,n)}else r=!0}}else e.insertBefore(o,n);return[o]}var ce=Q('
        '),ue=Q('
        ');const de=e=>{const{title:t,showBackBtn:n,onBack:r,onClose:o}=e;return i=ce(),s=i.firstChild,a=s.nextSibling,re(i,(l=P((()=>!!(null==n?void 0:n()))),()=>{return l()&&(ne(e=ue(),"click",r),e);var e}),s),re(s,t),a.$$click=()=>o(),i;var l,i,s,a};ee(["click"]);var fe=Q('
        ');const ge=e=>{const t=e,{showBackBtn:n,onBack:r,onClose:o,title:l}=t,i=s(t,["showBackBtn","onBack","onClose","title"]);return a=fe(),c=a.firstChild,u=c.firstChild,re(c,Y(de,{title:l,showBackBtn:n,onBack:r,onClose:o}),u),re(u,(()=>{var e;return null==(e=i.children)?void 0:e.call(i)})),re(a,(()=>{var e;return null==(e=i.extras)?void 0:e.call(i)}),null),S((()=>te(c,"data-dialog-name",e.name))),a;var a,c,u};let pe=null,he=null;const ve=()=>{pe&&clearInterval(pe),he&&window.removeEventListener("message",he)},me=(e,t)=>{const{user:n,token:r}=t;e.get("user").update({nick:n.name,email:n.email,link:n.link,isAdmin:n.is_admin,token:r})},ye=(e,t)=>{e.get("user").update({token:t}),e.getApi().user.getUser().then((t=>{const{user:n}=t.data;e.get("user").update({nick:n.name,email:n.email,link:n.link,isAdmin:n.is_admin})}))};var be=Q("
        "),ke=Q("
        "),we=Q("
        ");const $e=e=>{const{ctx:t,methods:n}=e;e.changeTitle(t.$t("signIn"));const r=n=>{n.onClick?n.onClick():n.link&&(()=>{a(this,null,(function*(){const r=/^(http|https):\/\//.test(n.link)?n.link:`${t.getConf().server}${n.link}`,{token:o}=yield((e,t)=>{ve();const n=(window.innerWidth-1020)/2,r=(window.innerHeight-618)/2,o=window.open(t,"_blank",`width=1020,height=618,left=${n},top=${r},scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no`);return new Promise(((e,t)=>{pe=setInterval((()=>{if(null==o?void 0:o.closed)return ve(),void t(new Error("Login canceled"));null==o||o.postMessage({type:"ATK_LOGIN"},"*")}),1e3),he=({data:t})=>{"ATK_AUTH_CALLBACK"===t.type&&t.payload&&(ve(),null==o||o.close(),e({token:t.payload}))},window.addEventListener("message",he)}))})(0,r);ye(t,o),e.onComplete()}))})()};O((()=>{var e;if(1===(null==(e=n())?void 0:e.length)){const e=n()[0];r(e)}}));const o=(re(l=be(),Y(Z,{get each(){return n()},children:e=>{return t=ke(),n=t.firstChild,o=n.nextSibling,t.$$click=()=>r(e),re(o,(()=>e.label)),S((r=>{var o=e.name,l=`url('${e.icon}')`;return o!==r.e&&te(t,"data-method",r.e=o),l!==r.t&&(null!=(r.t=l)?n.style.setProperty("background-image",l):n.style.removeProperty("background-image")),r}),{e:void 0,t:void 0}),t;var t,n,o}})),l);var l,i;return re(i=we(),o),i};ee(["click"]);const Ae=Symbol("store-raw"),xe=Symbol("store-node"),Ce=Symbol("store-has"),Se=Symbol("store-self");function Oe(e){let t=e[c];if(!t&&(Object.defineProperty(e,c,{value:t=new Proxy(e,_e)}),!Array.isArray(e))){const n=Object.keys(e),r=Object.getOwnPropertyDescriptors(e);for(let o=0,l=n.length;ot===Ae||t===c||t===u||t===xe||t===Ce||"__proto__"===t||(E()&&Te(Be(e,Ce),t)(),t in e),set:()=>!0,deleteProperty:()=>!0,ownKeys:function(e){return Ee(e),Reflect.ownKeys(e)},getOwnPropertyDescriptor:function(e,t){const n=Reflect.getOwnPropertyDescriptor(e,t);return n&&!n.get&&n.configurable&&t!==c&&t!==xe?(delete n.value,delete n.writable,n.get=()=>e[c][t],n):n}};function Le(e,t,n,r=!1){if(!r&&e[t]===n)return;const o=e[t],l=e.length;void 0===n?(delete e[t],e[Ce]&&e[Ce][t]&&void 0!==o&&e[Ce][t].$()):(e[t]=n,e[Ce]&&e[Ce][t]&&void 0===o&&e[Ce][t].$());let i,s=Be(e,xe);if((i=Te(s,t,o))&&i.$((()=>n)),Array.isArray(e)&&e.length!==l){for(let t=e.length;t1){r=t.shift();const l=typeof r,i=Array.isArray(e);if(Array.isArray(r)){for(let o=0;o1)return void Ie(e[r],t,[r].concat(n));o=e[r],n=[r].concat(n)}let l=t[0];"function"==typeof l&&(l=l(o,n),l===o)||void 0===r&&null==l||(l=je(l),void 0===r||Pe(o)&&Pe(l)&&!Array.isArray(l)?De(o,l):Le(e,r,l))}function qe(...[e,t]){const n=je(e||{}),r=Array.isArray(n);return[Oe(n),function(...e){M((()=>{r&&1===e.length?function(e,t){if("function"==typeof t&&(t=t(e)),t=je(t),Array.isArray(t)){if(e===t)return;let n=0,r=t.length;for(;n