karin-plugin-kkk 2.27.2 → 2.27.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/lib/apps/__ready.js +1 -2
  3. package/lib/apps/admin.js +1 -2
  4. package/lib/apps/help.js +1 -2
  5. package/lib/apps/push.js +1 -2
  6. package/lib/apps/qrlogin.js +1 -2
  7. package/lib/apps/statistics.js +1 -2
  8. package/lib/apps/tools.js +1 -2
  9. package/lib/apps/update.js +1 -2
  10. package/lib/build-metadata.json +5 -5
  11. package/lib/core_chunk/ArticleWork-B_N5AkIO.js +2 -0
  12. package/lib/core_chunk/Comment-3FcCu8BO.js +2 -0
  13. package/lib/core_chunk/Comment-B114EV7_.js +2 -0
  14. package/lib/core_chunk/Comment-DnBi7suz.js +2 -0
  15. package/lib/core_chunk/Comment-jN3Jrbqy.js +2 -0
  16. package/lib/core_chunk/DYNAMIC_TYPE_ARTICLE-DIZ4FpfS.js +2 -0
  17. package/lib/core_chunk/DYNAMIC_TYPE_AV-5WXLprJ7.js +2 -0
  18. package/lib/core_chunk/DYNAMIC_TYPE_DRAW-CA3dYbCJ.js +2 -0
  19. package/lib/core_chunk/DYNAMIC_TYPE_FORWARD-DEna4cpV.js +2 -0
  20. package/lib/core_chunk/DYNAMIC_TYPE_LIVE_RCMD-BpDR7WHh.js +2 -0
  21. package/lib/core_chunk/DYNAMIC_TYPE_WORD-uj6LDApK.js +2 -0
  22. package/lib/core_chunk/Dynamic-CjBqyS5b.js +2 -0
  23. package/lib/core_chunk/FavoriteList-DqEIdIRs.js +2 -0
  24. package/lib/core_chunk/GlobalStatistics-CjRmAre5.js +2 -0
  25. package/lib/core_chunk/GroupStatistics-B1KiWL8O.js +2 -0
  26. package/lib/core_chunk/Help-cUrYFfcV.js +2 -0
  27. package/lib/core_chunk/ImageWork-Q04TjdP2.js +2 -0
  28. package/lib/core_chunk/Live-9Ap-uSUG.js +2 -0
  29. package/lib/core_chunk/MusicInfo-DTgkPZdV.js +2 -0
  30. package/lib/core_chunk/RecommendList-zmL3tGkI.js +2 -0
  31. package/lib/core_chunk/UserList-DXZAtRSu.js +2 -0
  32. package/lib/core_chunk/UserList-DpZY5fHU.js +2 -0
  33. package/lib/core_chunk/UserVideoList-BjL0jy7v.js +2 -0
  34. package/lib/core_chunk/VersionWarning-Brat9oYa.js +2 -0
  35. package/lib/core_chunk/VideoWork-BNvQCKg2.js +2 -0
  36. package/lib/core_chunk/amagiClient-ATxzS7iY.js +2 -0
  37. package/lib/core_chunk/bangumi-Dn8bqGCx.js +2 -0
  38. package/lib/core_chunk/changelog-BEPsRL3p.js +2 -0
  39. package/lib/core_chunk/{db-BDAEWTrG.js → db-UHhoG96T.js} +1 -2
  40. package/lib/core_chunk/dist-BN09jDjE.js +2 -0
  41. package/lib/core_chunk/handlerError-BdKMBVs1.js +2 -0
  42. package/lib/core_chunk/{main-6QQJ5H3C.js → main-6Y7nyjx4.js} +170 -79
  43. package/lib/core_chunk/noteInfo-ceSqTSrs.js +2 -0
  44. package/lib/core_chunk/qrcodeImg-8IjCL_dz.js +2 -0
  45. package/lib/core_chunk/qrcodeImg-DYsRwngE.js +2 -0
  46. package/lib/core_chunk/qrlogin-zLF4JsCE.js +2 -0
  47. package/lib/core_chunk/setup-9JCJqKat.js +2 -0
  48. package/lib/core_chunk/template.d.mts +13 -13
  49. package/lib/core_chunk/template.js +1 -2
  50. package/lib/core_chunk/{vendor-CupLbLdw.js → vendor-C2bazYnS.js} +3088 -2097
  51. package/lib/core_chunk/videoInfo-C6b97ZWx.js +2 -0
  52. package/lib/core_chunk/videoInfo-JeaHNtaa.js +2 -0
  53. package/lib/index.js +1 -1
  54. package/lib/root.js +1 -1
  55. package/lib/web.config.js +1 -2
  56. package/package.json +2 -2
  57. package/lib/core_chunk/ArticleWork-D-BYrsdY.js +0 -3
  58. package/lib/core_chunk/Comment-BCBpHyDJ.js +0 -3
  59. package/lib/core_chunk/Comment-C_YwQUnb.js +0 -3
  60. package/lib/core_chunk/Comment-Cp0STr1s.js +0 -3
  61. package/lib/core_chunk/Comment-uFQ-lSTU.js +0 -3
  62. package/lib/core_chunk/DYNAMIC_TYPE_ARTICLE-BANrixjv.js +0 -3
  63. package/lib/core_chunk/DYNAMIC_TYPE_AV-B1j0DOxj.js +0 -3
  64. package/lib/core_chunk/DYNAMIC_TYPE_DRAW-BP5y2-Z0.js +0 -3
  65. package/lib/core_chunk/DYNAMIC_TYPE_FORWARD-Dqtxcfs5.js +0 -3
  66. package/lib/core_chunk/DYNAMIC_TYPE_LIVE_RCMD-BKK-MQIo.js +0 -3
  67. package/lib/core_chunk/DYNAMIC_TYPE_WORD-CExu1AeI.js +0 -3
  68. package/lib/core_chunk/Dynamic-BQRdF0Iq.js +0 -3
  69. package/lib/core_chunk/FavoriteList-CXaUjA4Z.js +0 -3
  70. package/lib/core_chunk/GlobalStatistics-PgMjuEI0.js +0 -3
  71. package/lib/core_chunk/GroupStatistics-BQc8xoUG.js +0 -3
  72. package/lib/core_chunk/Help-DxWnO364.js +0 -3
  73. package/lib/core_chunk/ImageWork-CAXTExbl.js +0 -3
  74. package/lib/core_chunk/Live-BPt0WjxN.js +0 -3
  75. package/lib/core_chunk/MusicInfo-CbpQDtXR.js +0 -3
  76. package/lib/core_chunk/RecommendList-CSGMmQHV.js +0 -3
  77. package/lib/core_chunk/UserList-Dlfezkg4.js +0 -3
  78. package/lib/core_chunk/UserList-ZtuCbZcD.js +0 -3
  79. package/lib/core_chunk/UserVideoList-DsfmDdbu.js +0 -3
  80. package/lib/core_chunk/VersionWarning-BBilm7ZQ.js +0 -3
  81. package/lib/core_chunk/VideoWork-Mp9SYOhU.js +0 -3
  82. package/lib/core_chunk/amagiClient-DVxH7OHV.js +0 -3
  83. package/lib/core_chunk/bangumi-Ch7mnoug.js +0 -3
  84. package/lib/core_chunk/changelog-e1jZ80d5.js +0 -3
  85. package/lib/core_chunk/dist-Cx4SNJ6B.js +0 -2
  86. package/lib/core_chunk/handlerError-DsnWvz4S.js +0 -3
  87. package/lib/core_chunk/noteInfo-D_BhS1le.js +0 -3
  88. package/lib/core_chunk/qrcodeImg-CZjyVFex.js +0 -3
  89. package/lib/core_chunk/qrcodeImg-CzvTO1mE.js +0 -3
  90. package/lib/core_chunk/qrlogin-FkNz8tfK.js +0 -3
  91. package/lib/core_chunk/setup-B-PwgJem.js +0 -3
  92. package/lib/core_chunk/videoInfo-2ZftvrcH.js +0 -3
  93. package/lib/core_chunk/videoInfo-Bnv5saba.js +0 -3
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM } from "./rolldown-runtime-8i3BgXHp.js";
2
- import { $ as RiTrophyFill, $t as require_qr_code_styling, A as RiBellFill, At as Eye, B as RiLoginCircleFill, Bt as ChartColumn, C as AiOutlineVideoCamera, Ct as MapPin, D as LuFullscreen, Dt as Gift, E as SiBilibili, Et as Hash, F as RiHeart3Line, Ft as Clock, G as RiRobot2Fill, Gt as require_dist, H as RiPieChart2Fill, Ht as Bookmark, I as RiLineChartFill, It as CircleFadingArrowUp, J as RiSparkling2Fill, Jt as zhCN, K as RiSendPlaneFill, Kt as require_lib, L as RiLinkM, Lt as CircleEllipsis, M as RiHashtag, Mt as Crown, N as RiHeart2Line, Nt as CornerDownLeft, O as RiArrowRightFill, Ot as Gamepad2, P as RiHeart3Fill, Pt as Coins, Q as RiTiktokFill, Qt as differenceInSeconds, R as RiListCheck2, Rt as CircleCheckBig, S as AiFillStar, St as MessageCircle, T as Markdown, Tt as Heart, U as RiQuestionFill, Ut as BookOpen, V as RiMessage3Fill, Vt as Calendar, W as RiRefreshLine, Wt as Bell, X as RiStarLine, Xt as formatDistanceToNow, Y as RiStarFill, Yt as fromUnixTime, Z as RiThumbUpFill, Zt as format, _ as FaTiktok, _n as axios$1, _t as Quote, a as VictoryChart, an as HeroUIProvider, at as User, b as AiFillHeart, bt as Play, c as VictoryTheme, cn as require_react, ct as ThumbsUp, d as MdAccessTime, dn as require_jpeg_js, dt as Smartphone, en as Window, et as RiUserFollowLine, f as MdLocationOn, fn as require_heic_decode, ft as Shield, g as FaMusic, gn as AxiosError$1, gt as Radio, h as FaCommentDots, hn as Chalk, ht as ScanLine, i as VictoryLine, in as button_default, it as Users, j as RiGroupLine, jt as ExternalLink, k as RiBarChartFill, kt as FileText, l as TbScan, ln as require_png, lt as Terminal, m as FaCodeBranch, mn as require_protobufjs, mt as Share2, n as VictoryScatter, nn as code_default, nt as RiVideoLine, o as VictoryAxis, on as require_jsx_runtime, ot as UserPlus, p as MdOutlineLightbulb, pn as require_express, pt as ShieldCheck, q as RiShareForwardFill, r as VictoryPie, rn as chip_default, rt as Zap, s as VictoryLabel, sn as clsx, st as TriangleAlert, t as rehypeHighlight, tn as require_server_node, tt as RiVerifiedBadgeFill, u as HiOutlineMenuAlt2, un as require_jsQR, ut as Star, v as FaUserGroup, vn as Xhshow, vt as QrCode, w as IoSearch, wt as Info, x as AiFillPushpin, xt as Music, y as BsImage, yn as zod_default, yt as Plug2, z as RiLiveLine, zt as CircleAlert } from "./vendor-CupLbLdw.js";
2
+ import { $ as RiTrophyFill, $t as require_qr_code_styling, A as RiBellFill, At as Eye, B as RiLoginCircleFill, Bt as ChartColumn, C as AiOutlineVideoCamera, Ct as MapPin, D as LuFullscreen, Dt as Gift, E as SiBilibili, Et as Hash, F as RiHeart3Line, Ft as Clock, G as RiRobot2Fill, Gt as require_dist, H as RiPieChart2Fill, Ht as Bookmark, I as RiLineChartFill, It as CircleFadingArrowUp, J as RiSparkling2Fill, Jt as zhCN, K as RiSendPlaneFill, Kt as require_lib, L as RiLinkM, Lt as CircleEllipsis, M as RiHashtag, Mt as Crown, N as RiHeart2Line, Nt as CornerDownLeft, O as RiArrowRightFill, Ot as Gamepad2, P as RiHeart3Fill, Pt as Coins, Q as RiTiktokFill, Qt as differenceInSeconds, R as RiListCheck2, Rt as CircleCheckBig, S as AiFillStar, St as MessageCircle, T as Markdown, Tt as Heart, U as RiQuestionFill, Ut as BookOpen, V as RiMessage3Fill, Vt as Calendar, W as RiRefreshLine, Wt as Bell, X as RiStarLine, Xt as formatDistanceToNow, Y as RiStarFill, Yt as fromUnixTime, Z as RiThumbUpFill, Zt as format, _ as FaTiktok, _n as AxiosError$1, _t as Quote, a as VictoryChart, an as button_default, at as User, b as AiFillHeart, bn as zod_default, bt as Play, c as VictoryTheme, cn as clsx, ct as ThumbsUp, d as MdAccessTime, dn as require_jsQR, dt as Smartphone, en as Window, et as RiUserFollowLine, f as MdLocationOn, fn as require_jpeg_js, ft as Shield, g as FaMusic, gn as Chalk, gt as Radio, h as FaCommentDots, hn as require_protobufjs, ht as ScanLine, i as VictoryLine, in as chip_default, it as Users, j as RiGroupLine, jt as ExternalLink, k as RiBarChartFill, kt as FileText, l as TbScan, ln as require_react, lt as Terminal, m as FaCodeBranch, mn as require_express, mt as Share2, n as VictoryScatter, nn as require_server_node, nt as RiVideoLine, o as VictoryAxis, on as HeroUIProvider, ot as UserPlus, p as MdOutlineLightbulb, pn as require_heic_decode, pt as ShieldCheck, q as RiShareForwardFill, r as VictoryPie, rn as code_default, rt as Zap, s as VictoryLabel, sn as require_jsx_runtime, st as TriangleAlert, t as rehypeHighlight, tn as purify, tt as RiVerifiedBadgeFill, u as HiOutlineMenuAlt2, un as require_png, ut as Star, v as FaUserGroup, vn as axios$1, vt as QrCode, w as IoSearch, wt as Info, x as AiFillPushpin, xt as Music, y as BsImage, yn as Xhshow, yt as Plug2, z as RiLiveLine, zt as CircleAlert } from "./vendor-C2bazYnS.js";
3
3
  import "node:module";
4
4
  import fs from "node:fs";
5
5
  import path, { resolve } from "node:path";
@@ -21,7 +21,7 @@ import { snapka } from "@snapka/puppeteer";
21
21
  import { newInjectedPage } from "fingerprint-injector";
22
22
  import express from "node-karin/express";
23
23
  globalThis.__kkkLoadStart ??= process.hrtime.bigint();
24
- import("./setup-B-PwgJem.js");
24
+ import("./setup-9JCJqKat.js");
25
25
  var resolvePluginRoot = (startUrl) => {
26
26
  let dir = path.dirname(startUrl);
27
27
  for (let i = 0; i < 8; i++) {
@@ -5213,7 +5213,7 @@ var Cfg = class {
5213
5213
  const fileName = path.basename(file, ".yaml");
5214
5214
  if (fileName === "cookies" || fileName === "request") {
5215
5215
  logger.debug(`[Config] 检测到 ${fileName} 配置变化,正在重载 Amagi Client...`);
5216
- import("./amagiClient-DVxH7OHV.js").then(({ reloadAmagiConfig }) => {
5216
+ import("./amagiClient-ATxzS7iY.js").then(({ reloadAmagiConfig }) => {
5217
5217
  reloadAmagiConfig();
5218
5218
  }).catch((error) => {
5219
5219
  logger.error(`[Config] 重载 Amagi Client 失败: ${error}`);
@@ -5232,7 +5232,7 @@ var Cfg = class {
5232
5232
  };
5233
5233
  }
5234
5234
  async All() {
5235
- const { getDouyinDB, getBilibiliDB } = await import("./db-BDAEWTrG.js");
5235
+ const { getDouyinDB, getBilibiliDB } = await import("./db-UHhoG96T.js");
5236
5236
  const douyinDB = await getDouyinDB();
5237
5237
  const bilibiliDB = await getBilibiliDB();
5238
5238
  const allConfig = {};
@@ -5274,7 +5274,7 @@ var Cfg = class {
5274
5274
  fs.writeFileSync(path, yamlData.toString({ lineWidth: -1 }), "utf8");
5275
5275
  }
5276
5276
  async ModifyPro(name, config, type = "config") {
5277
- const { getDouyinDB, getBilibiliDB } = await import("./db-BDAEWTrG.js");
5277
+ const { getDouyinDB, getBilibiliDB } = await import("./db-UHhoG96T.js");
5278
5278
  const douyinDB = await getDouyinDB();
5279
5279
  const bilibiliDB = await getBilibiliDB();
5280
5280
  const filePath = type === "config" ? `${this.dirCfgPath}/${name}.yaml` : `${this.defCfgPath}/${name}.yaml`;
@@ -5379,7 +5379,7 @@ var Cfg = class {
5379
5379
  }
5380
5380
  async syncConfigToDatabase() {
5381
5381
  try {
5382
- const { getDouyinDB, getBilibiliDB } = await import("./db-BDAEWTrG.js");
5382
+ const { getDouyinDB, getBilibiliDB } = await import("./db-UHhoG96T.js");
5383
5383
  const douyinDB = await getDouyinDB();
5384
5384
  const bilibiliDB = await getBilibiliDB();
5385
5385
  const pushCfg = this.getYaml("config", "pushlist");
@@ -5494,8 +5494,15 @@ var AmagiBase = class {
5494
5494
  return createProxy(client);
5495
5495
  };
5496
5496
  };
5497
+ var createLiveProxy = (getter) => new Proxy({}, { get(_target, prop) {
5498
+ const current = getter();
5499
+ const value = Reflect.get(current, prop);
5500
+ if (typeof value === "function") return value.bind(current);
5501
+ if (value && typeof value === "object") return createLiveProxy(() => Reflect.get(getter(), prop));
5502
+ return value;
5503
+ } });
5497
5504
  var amagiClientInstance = new AmagiBase();
5498
- var amagiClient = amagiClientInstance.amagi;
5505
+ var amagiClient = createLiveProxy(() => amagiClientInstance.amagi);
5499
5506
  var reloadAmagiConfig = () => {
5500
5507
  amagiClientInstance.reloadConfig();
5501
5508
  };
@@ -8023,47 +8030,47 @@ var componentConfigs = baseComponentConfigs.map((basePlatform) => {
8023
8030
  switch (baseComponent.id) {
8024
8031
  case "comment": return createComponentConfig(baseComponent, {
8025
8032
  validateData: (data) => data && typeof data.share_url === "string",
8026
- lazyComponent: () => import("./Comment-BCBpHyDJ.js").then((module) => ({ default: module.DouyinComment }))
8033
+ lazyComponent: () => import("./Comment-jN3Jrbqy.js").then((module) => ({ default: module.DouyinComment }))
8027
8034
  });
8028
8035
  case "dynamic": return createComponentConfig(baseComponent, {
8029
8036
  validateData: (data) => data && typeof data.share_url === "string",
8030
- lazyComponent: () => import("./Dynamic-BQRdF0Iq.js").then((module) => ({ default: module.DouyinDynamic }))
8037
+ lazyComponent: () => import("./Dynamic-CjBqyS5b.js").then((module) => ({ default: module.DouyinDynamic }))
8031
8038
  });
8032
8039
  case "video-work": return createComponentConfig(baseComponent, {
8033
8040
  validateData: (data) => data && typeof data.share_url === "string",
8034
- lazyComponent: () => import("./VideoWork-Mp9SYOhU.js").then((module) => ({ default: module.DouyinVideoWork }))
8041
+ lazyComponent: () => import("./VideoWork-BNvQCKg2.js").then((module) => ({ default: module.DouyinVideoWork }))
8035
8042
  });
8036
8043
  case "image-work": return createComponentConfig(baseComponent, {
8037
8044
  validateData: (data) => data && typeof data.share_url === "string",
8038
- lazyComponent: () => import("./ImageWork-CAXTExbl.js").then((module) => ({ default: module.DouyinImageWork }))
8045
+ lazyComponent: () => import("./ImageWork-Q04TjdP2.js").then((module) => ({ default: module.DouyinImageWork }))
8039
8046
  });
8040
8047
  case "article-work": return createComponentConfig(baseComponent, {
8041
8048
  validateData: (data) => data && typeof data.share_url === "string",
8042
- lazyComponent: () => import("./ArticleWork-D-BYrsdY.js").then((module) => ({ default: module.DouyinArticleWork }))
8049
+ lazyComponent: () => import("./ArticleWork-B_N5AkIO.js").then((module) => ({ default: module.DouyinArticleWork }))
8043
8050
  });
8044
8051
  case "favorite-list": return createComponentConfig(baseComponent, {
8045
8052
  validateData: (data) => data && typeof data.share_url === "string",
8046
- lazyComponent: () => import("./FavoriteList-CXaUjA4Z.js").then((module) => ({ default: module.DouyinFavoriteList }))
8053
+ lazyComponent: () => import("./FavoriteList-DqEIdIRs.js").then((module) => ({ default: module.DouyinFavoriteList }))
8047
8054
  });
8048
8055
  case "recommend-list": return createComponentConfig(baseComponent, {
8049
8056
  validateData: (data) => data && typeof data.share_url === "string",
8050
- lazyComponent: () => import("./RecommendList-CSGMmQHV.js").then((module) => ({ default: module.DouyinRecommendList }))
8057
+ lazyComponent: () => import("./RecommendList-zmL3tGkI.js").then((module) => ({ default: module.DouyinRecommendList }))
8051
8058
  });
8052
8059
  case "live": return createComponentConfig(baseComponent, {
8053
8060
  validateData: (data) => data && typeof data.share_url === "string",
8054
- lazyComponent: () => import("./Live-BPt0WjxN.js").then((module) => ({ default: module.DouyinLive }))
8061
+ lazyComponent: () => import("./Live-9Ap-uSUG.js").then((module) => ({ default: module.DouyinLive }))
8055
8062
  });
8056
8063
  case "musicinfo": return createComponentConfig(baseComponent, {
8057
8064
  validateData: (data) => data && typeof data.share_url === "string",
8058
- lazyComponent: () => import("./MusicInfo-CbpQDtXR.js").then((module) => ({ default: module.DouyinMusicInfo }))
8065
+ lazyComponent: () => import("./MusicInfo-DTgkPZdV.js").then((module) => ({ default: module.DouyinMusicInfo }))
8059
8066
  });
8060
- case "user_profile": return createComponentConfig(baseComponent, { lazyComponent: () => import("./UserVideoList-DsfmDdbu.js").then((module) => ({ default: module.DouyinUserVideoList })) });
8067
+ case "user_profile": return createComponentConfig(baseComponent, { lazyComponent: () => import("./UserVideoList-BjL0jy7v.js").then((module) => ({ default: module.DouyinUserVideoList })) });
8061
8068
  case "userlist": return createComponentConfig(baseComponent, {
8062
8069
  validateData: (data) => data && Array.isArray(data.renderOpt),
8063
- lazyComponent: () => import("./UserList-ZtuCbZcD.js").then((module) => ({ default: module.default }))
8070
+ lazyComponent: () => import("./UserList-DpZY5fHU.js").then((module) => ({ default: module.default }))
8064
8071
  });
8065
- case "videoInfo": return createComponentConfig(baseComponent, { lazyComponent: () => import("./videoInfo-Bnv5saba.js").then((module) => ({ default: module.DouyinVideoInfo })) });
8066
- case "qrcodeImg": return createComponentConfig(baseComponent, { lazyComponent: () => import("./qrcodeImg-CzvTO1mE.js").then((module) => ({ default: module.DouyinQrcodeImg })) });
8072
+ case "videoInfo": return createComponentConfig(baseComponent, { lazyComponent: () => import("./videoInfo-JeaHNtaa.js").then((module) => ({ default: module.DouyinVideoInfo })) });
8073
+ case "qrcodeImg": return createComponentConfig(baseComponent, { lazyComponent: () => import("./qrcodeImg-DYsRwngE.js").then((module) => ({ default: module.DouyinQrcodeImg })) });
8067
8074
  default: return createComponentConfig(baseComponent);
8068
8075
  }
8069
8076
  });
@@ -8073,42 +8080,42 @@ var componentConfigs = baseComponentConfigs.map((basePlatform) => {
8073
8080
  switch (baseComponent.id) {
8074
8081
  case "comment": return createComponentConfig(baseComponent, {
8075
8082
  validateData: (data) => data && typeof data.share_url === "string",
8076
- lazyComponent: () => import("./Comment-Cp0STr1s.js").then((module) => ({ default: module.BilibiliComment }))
8083
+ lazyComponent: () => import("./Comment-DnBi7suz.js").then((module) => ({ default: module.BilibiliComment }))
8077
8084
  });
8078
8085
  case "userlist": return createComponentConfig(baseComponent, {
8079
8086
  validateData: (data) => data && Array.isArray(data.renderOpt),
8080
- lazyComponent: () => import("./UserList-Dlfezkg4.js").then((module) => ({ default: module.default }))
8087
+ lazyComponent: () => import("./UserList-DXZAtRSu.js").then((module) => ({ default: module.default }))
8081
8088
  });
8082
- case "bangumi": return createComponentConfig(baseComponent, { lazyComponent: () => import("./bangumi-Ch7mnoug.js").then((module) => ({ default: module.default })) });
8089
+ case "bangumi": return createComponentConfig(baseComponent, { lazyComponent: () => import("./bangumi-Dn8bqGCx.js").then((module) => ({ default: module.default })) });
8083
8090
  case "dynamic/DYNAMIC_TYPE_DRAW": return createComponentConfig(baseComponent, {
8084
8091
  validateData: (data) => data && typeof data.share_url === "string",
8085
- lazyComponent: () => import("./DYNAMIC_TYPE_DRAW-BP5y2-Z0.js").then((module) => ({ default: module.BilibiliDrawDynamic }))
8092
+ lazyComponent: () => import("./DYNAMIC_TYPE_DRAW-CA3dYbCJ.js").then((module) => ({ default: module.BilibiliDrawDynamic }))
8086
8093
  });
8087
8094
  case "dynamic/DYNAMIC_TYPE_WORD": return createComponentConfig(baseComponent, {
8088
8095
  validateData: (data) => data && typeof data.share_url === "string",
8089
- lazyComponent: () => import("./DYNAMIC_TYPE_WORD-CExu1AeI.js").then((module) => ({ default: module.BilibiliWordDynamic }))
8096
+ lazyComponent: () => import("./DYNAMIC_TYPE_WORD-uj6LDApK.js").then((module) => ({ default: module.BilibiliWordDynamic }))
8090
8097
  });
8091
8098
  case "dynamic/DYNAMIC_TYPE_AV": return createComponentConfig(baseComponent, {
8092
8099
  validateData: (data) => data && typeof data.share_url === "string",
8093
- lazyComponent: () => import("./DYNAMIC_TYPE_AV-B1j0DOxj.js").then((module) => ({ default: module.BilibiliVideoDynamic }))
8100
+ lazyComponent: () => import("./DYNAMIC_TYPE_AV-5WXLprJ7.js").then((module) => ({ default: module.BilibiliVideoDynamic }))
8094
8101
  });
8095
8102
  case "dynamic/DYNAMIC_TYPE_FORWARD": return createComponentConfig(baseComponent, {
8096
8103
  validateData: (data) => data && typeof data.share_url === "string",
8097
- lazyComponent: () => import("./DYNAMIC_TYPE_FORWARD-Dqtxcfs5.js").then((module) => ({ default: module.BilibiliForwardDynamic }))
8104
+ lazyComponent: () => import("./DYNAMIC_TYPE_FORWARD-DEna4cpV.js").then((module) => ({ default: module.BilibiliForwardDynamic }))
8098
8105
  });
8099
8106
  case "dynamic/DYNAMIC_TYPE_LIVE_RCMD": return createComponentConfig(baseComponent, {
8100
8107
  validateData: (data) => data && typeof data.share_url === "string",
8101
- lazyComponent: () => import("./DYNAMIC_TYPE_LIVE_RCMD-BKK-MQIo.js").then((module) => ({ default: module.BilibiliLiveDynamic }))
8108
+ lazyComponent: () => import("./DYNAMIC_TYPE_LIVE_RCMD-BpDR7WHh.js").then((module) => ({ default: module.BilibiliLiveDynamic }))
8102
8109
  });
8103
8110
  case "dynamic/DYNAMIC_TYPE_WORD": return createComponentConfig(baseComponent, { validateData: (data) => data && typeof data.share_url === "string" });
8104
- case "dynamic/DYNAMIC_TYPE_ARTICLE": return createComponentConfig(baseComponent, { lazyComponent: () => import("./DYNAMIC_TYPE_ARTICLE-BANrixjv.js").then((module) => ({ default: module.BilibiliArticleDynamic })) });
8111
+ case "dynamic/DYNAMIC_TYPE_ARTICLE": return createComponentConfig(baseComponent, { lazyComponent: () => import("./DYNAMIC_TYPE_ARTICLE-DIZ4FpfS.js").then((module) => ({ default: module.BilibiliArticleDynamic })) });
8105
8112
  case "videoInfo": return createComponentConfig(baseComponent, {
8106
8113
  validateData: (data) => data && typeof data.share_url === "string",
8107
- lazyComponent: () => import("./videoInfo-2ZftvrcH.js").then((module) => ({ default: module.BilibiliVideoInfo }))
8114
+ lazyComponent: () => import("./videoInfo-C6b97ZWx.js").then((module) => ({ default: module.BilibiliVideoInfo }))
8108
8115
  });
8109
8116
  case "qrcodeImg": return createComponentConfig(baseComponent, {
8110
8117
  validateData: (data) => data && typeof data.share_url === "string",
8111
- lazyComponent: () => import("./qrcodeImg-CZjyVFex.js").then((module) => ({ default: module.BilibiliQrcodeImg }))
8118
+ lazyComponent: () => import("./qrcodeImg-8IjCL_dz.js").then((module) => ({ default: module.BilibiliQrcodeImg }))
8112
8119
  });
8113
8120
  default: return createComponentConfig(baseComponent);
8114
8121
  }
@@ -8119,7 +8126,7 @@ var componentConfigs = baseComponentConfigs.map((basePlatform) => {
8119
8126
  switch (baseComponent.id) {
8120
8127
  case "comment": return createComponentConfig(baseComponent, {
8121
8128
  validateData: (data) => data && typeof data.share_url === "string",
8122
- lazyComponent: () => import("./Comment-uFQ-lSTU.js").then((module) => ({ default: module.KuaishouComment }))
8129
+ lazyComponent: () => import("./Comment-B114EV7_.js").then((module) => ({ default: module.KuaishouComment }))
8123
8130
  });
8124
8131
  default: return createComponentConfig(baseComponent);
8125
8132
  }
@@ -8128,8 +8135,8 @@ var componentConfigs = baseComponentConfigs.map((basePlatform) => {
8128
8135
  case PlatformType.XIAOHONGSHU:
8129
8136
  platform.components = basePlatform.components.map((baseComponent) => {
8130
8137
  switch (baseComponent.id) {
8131
- case "noteInfo": return createComponentConfig(baseComponent, { lazyComponent: () => import("./noteInfo-D_BhS1le.js").then((module) => ({ default: module.XiaohongshuNoteInfo })) });
8132
- case "comment": return createComponentConfig(baseComponent, { lazyComponent: () => import("./Comment-C_YwQUnb.js").then((module) => ({ default: module.XiaohongshuComment })) });
8138
+ case "noteInfo": return createComponentConfig(baseComponent, { lazyComponent: () => import("./noteInfo-ceSqTSrs.js").then((module) => ({ default: module.XiaohongshuNoteInfo })) });
8139
+ case "comment": return createComponentConfig(baseComponent, { lazyComponent: () => import("./Comment-3FcCu8BO.js").then((module) => ({ default: module.XiaohongshuComment })) });
8133
8140
  default: return createComponentConfig(baseComponent);
8134
8141
  }
8135
8142
  });
@@ -8137,11 +8144,11 @@ var componentConfigs = baseComponentConfigs.map((basePlatform) => {
8137
8144
  case PlatformType.OTHER:
8138
8145
  platform.components = basePlatform.components.map((baseComponent) => {
8139
8146
  switch (baseComponent.id) {
8140
- case "help": return createComponentConfig(baseComponent, { lazyComponent: () => import("./Help-DxWnO364.js").then((module) => ({ default: module.default })) });
8141
- case "handlerError": return createComponentConfig(baseComponent, { lazyComponent: () => import("./handlerError-DsnWvz4S.js").then((module) => ({ default: module.handlerError })) });
8142
- case "changelog": return createComponentConfig(baseComponent, { lazyComponent: () => import("./changelog-e1jZ80d5.js").then((module) => ({ default: module.Changelog })) });
8143
- case "version_warning": return createComponentConfig(baseComponent, { lazyComponent: () => import("./VersionWarning-BBilm7ZQ.js").then((module) => ({ default: module.VersionWarning })) });
8144
- case "qrlogin": return createComponentConfig(baseComponent, { lazyComponent: () => import("./qrlogin-FkNz8tfK.js").then((module) => ({ default: module.QrLogin })) });
8147
+ case "help": return createComponentConfig(baseComponent, { lazyComponent: () => import("./Help-cUrYFfcV.js").then((module) => ({ default: module.default })) });
8148
+ case "handlerError": return createComponentConfig(baseComponent, { lazyComponent: () => import("./handlerError-BdKMBVs1.js").then((module) => ({ default: module.handlerError })) });
8149
+ case "changelog": return createComponentConfig(baseComponent, { lazyComponent: () => import("./changelog-BEPsRL3p.js").then((module) => ({ default: module.Changelog })) });
8150
+ case "version_warning": return createComponentConfig(baseComponent, { lazyComponent: () => import("./VersionWarning-Brat9oYa.js").then((module) => ({ default: module.VersionWarning })) });
8151
+ case "qrlogin": return createComponentConfig(baseComponent, { lazyComponent: () => import("./qrlogin-zLF4JsCE.js").then((module) => ({ default: module.QrLogin })) });
8145
8152
  default: return createComponentConfig(baseComponent);
8146
8153
  }
8147
8154
  });
@@ -8149,8 +8156,8 @@ var componentConfigs = baseComponentConfigs.map((basePlatform) => {
8149
8156
  case PlatformType.STATISTICS:
8150
8157
  platform.components = basePlatform.components.map((baseComponent) => {
8151
8158
  switch (baseComponent.id) {
8152
- case "group": return createComponentConfig(baseComponent, { lazyComponent: () => import("./GroupStatistics-BQc8xoUG.js").then((module) => ({ default: module.GroupStatistics })) });
8153
- case "global": return createComponentConfig(baseComponent, { lazyComponent: () => import("./GlobalStatistics-PgMjuEI0.js").then((module) => ({ default: module.GlobalStatistics })) });
8159
+ case "group": return createComponentConfig(baseComponent, { lazyComponent: () => import("./GroupStatistics-B1KiWL8O.js").then((module) => ({ default: module.GroupStatistics })) });
8160
+ case "global": return createComponentConfig(baseComponent, { lazyComponent: () => import("./GlobalStatistics-CjRmAre5.js").then((module) => ({ default: module.GlobalStatistics })) });
8154
8161
  default: return createComponentConfig(baseComponent);
8155
8162
  }
8156
8163
  });
@@ -8609,18 +8616,58 @@ var HtmlWrapper = class {
8609
8616
  constructor(resourceManager) {
8610
8617
  this.resourceManager = resourceManager;
8611
8618
  }
8619
+ getAssetMimeType(assetPath) {
8620
+ switch (path.extname(assetPath).toLowerCase()) {
8621
+ case ".woff2": return "font/woff2";
8622
+ case ".woff": return "font/woff";
8623
+ case ".ttf": return "font/ttf";
8624
+ case ".otf": return "font/otf";
8625
+ case ".eot": return "application/vnd.ms-fontobject";
8626
+ case ".svg": return "image/svg+xml";
8627
+ case ".png": return "image/png";
8628
+ case ".jpg":
8629
+ case ".jpeg": return "image/jpeg";
8630
+ case ".gif": return "image/gif";
8631
+ case ".webp": return "image/webp";
8632
+ case ".avif": return "image/avif";
8633
+ default: return "application/octet-stream";
8634
+ }
8635
+ }
8636
+ toDataUri(assetPath) {
8637
+ if (!fs.existsSync(assetPath)) {
8638
+ logger$1.warn("未找到静态资源文件,跳过内联:", assetPath);
8639
+ return null;
8640
+ }
8641
+ return `data:${this.getAssetMimeType(assetPath)};base64,${fs.readFileSync(assetPath).toString("base64")}`;
8642
+ }
8643
+ loadInlineCss(cssFilePath) {
8644
+ if (!fs.existsSync(cssFilePath)) {
8645
+ logger$1.warn("未找到 CSS 文件,跳过内联:", cssFilePath);
8646
+ return "";
8647
+ }
8648
+ const cssDir = path.dirname(cssFilePath);
8649
+ return fs.readFileSync(cssFilePath, "utf-8").replace(/url\((['"]?)(?!data:|https?:|file:|#)([^)'"]+)\1\)/g, (_match, quote, assetPath) => {
8650
+ const normalizedAssetPath = assetPath.trim();
8651
+ if (!normalizedAssetPath || normalizedAssetPath.startsWith("/")) return `url(${quote}${normalizedAssetPath}${quote})`;
8652
+ const absoluteAssetPath = path.resolve(cssDir, normalizedAssetPath);
8653
+ const dataUri = this.toDataUri(absoluteAssetPath);
8654
+ return dataUri ? `url(${quote}${dataUri}${quote})` : `url(${quote}${normalizedAssetPath}${quote})`;
8655
+ });
8656
+ }
8657
+ getInlineStyles(_htmlFilePath, includeFonts = true) {
8658
+ const { cssDir, imageDir } = this.resourceManager.getResourcePaths();
8659
+ const fontDir = path.join(path.dirname(imageDir), "font");
8660
+ const styleFiles = [path.join(cssDir, "karin-plugin-kkk.css")];
8661
+ if (includeFonts) styleFiles.unshift(path.join(fontDir, "bilifont", "font.css"), path.join(fontDir, "mono", "font.css"));
8662
+ return styleFiles.map((filePath) => this.loadInlineCss(filePath)).filter(Boolean).join("\n");
8663
+ }
8612
8664
  wrapContent(htmlContent, htmlFilePath, isDark = false) {
8613
8665
  const htmlDir = path.dirname(htmlFilePath);
8614
- const { cssDir, imageDir } = this.resourceManager.getResourcePaths();
8615
- const cssRelativePath = path.relative(htmlDir, cssDir).replace(/\\/g, "/");
8666
+ const { imageDir } = this.resourceManager.getResourcePaths();
8667
+ const inlineStyles = this.getInlineStyles(htmlFilePath);
8616
8668
  const imageRelativePath = path.relative(htmlDir, imageDir).replace(/\\/g, "/");
8617
- const cssUrl = path.join(cssRelativePath, "karin-plugin-kkk.css").replace(/\\/g, "/");
8618
- const fontDir = path.join(path.dirname(imageDir), "font");
8619
- const fontRelativePath = path.relative(htmlDir, fontDir).replace(/\\/g, "/");
8620
- const bilifontUrl = path.join(fontRelativePath, "bilifont/font.css").replace(/\\/g, "/");
8621
- const monoFontUrl = path.join(fontRelativePath, "mono/font.css").replace(/\\/g, "/");
8622
8669
  let processedHtml = htmlContent.replace(/src="\/image\//g, `src="${imageRelativePath}/`).replace(/src='\/image\//g, `src='${imageRelativePath}/`).replace(/src="image\//g, `src="${imageRelativePath}/`);
8623
- return `\n <!DOCTYPE html>\n <html lang="zh-CN">\n <head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width">\n <link rel="stylesheet" href="${bilifontUrl}">\n <link rel="stylesheet" href="${monoFontUrl}">\n <link rel="stylesheet" href="${cssUrl}">\n <style>\n html, body {\n margin: 0;\n padding: 0;\n background: transparent !important;\n }\n body {\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n }\n #container {\n border-radius: 3rem;\n overflow: hidden;\n background-clip: padding-box;\n }\n </style>\n </head>\n <body class="${isDark ? "dark" : ""}">\n ${processedHtml}\n </body>\n </html>\n `;
8670
+ return `\n <!DOCTYPE html>\n <html lang="zh-CN">\n <head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width">\n <style>${inlineStyles}</style>\n <style>\n html, body {\n margin: 0;\n padding: 0;\n background: transparent !important;\n }\n body {\n display: flex;\n align-items: flex-start;\n justify-content: flex-start;\n }\n #container {\n border-radius: 3rem;\n overflow: hidden;\n background-clip: padding-box;\n }\n </style>\n </head>\n <body class="${isDark ? "dark" : ""}">\n ${processedHtml}\n </body>\n </html>\n `;
8624
8671
  }
8625
8672
  };
8626
8673
  var SSRRender = class {
@@ -8698,9 +8745,7 @@ var renderVideoPreviewPage = (options) => {
8698
8745
  };
8699
8746
  const appHtml = (0, import_server_node.renderToString)(import_react.createElement(VideoPreviewApp, { state }));
8700
8747
  const serializedState = escapeVideoPreviewJson(state);
8701
- const { cssDir } = new ResourcePathManager().getResourcePaths();
8702
- const cssFilePath = path.join(cssDir, "karin-plugin-kkk.css");
8703
- return `<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <title>临时预览</title>\n <style>\n * { box-sizing: border-box; }\n :root { --preview-bg: #ffffff; --preview-fg: #0f172a; --preview-muted: #64748b; }\n @media (prefers-color-scheme: dark) {\n :root { --preview-bg: #050505; --preview-fg: #e2e8f0; --preview-muted: #94a3b8; }\n }\n body { margin: 0; font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: var(--preview-bg); color: var(--preview-fg); }\n .preview-noise { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.25'/%3E%3C/svg%3E"); mix-blend-mode: soft-light; opacity: 0.8; }\n @media (max-width: 720px) {\n .max-w-6xl { padding-left: 16px; padding-right: 16px; }\n }\n </style>\n <style>${fs.existsSync(cssFilePath) ? fs.readFileSync(cssFilePath, "utf-8") : ""}</style>\n</head>\n<body>\n <div id="app">${appHtml}</div>\n <script>\n window.__VIDEO_PREVIEW__=${serializedState};\n (() => {\n const state = window.__VIDEO_PREVIEW__ || {};\n const countdownEl = document.getElementById('preview-countdown');\n if (!countdownEl) return;\n const format = (ms) => {\n const totalSeconds = Math.max(Math.floor(ms / 1000), 0);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const pad = (value) => String(value).padStart(2, '0');\n return hours > 0 ? pad(hours) + ':' + pad(minutes) + ':' + pad(seconds) : pad(minutes) + ':' + pad(seconds);\n };\n const update = (payload) => {\n if (!payload.removeCache) {\n countdownEl.textContent = '不删除';\n return;\n }\n if (payload.removed) {\n countdownEl.textContent = '00:00';\n return;\n }\n const remainingMs = typeof payload.remainingMs === 'number'\n ? payload.remainingMs\n : (payload.expireAt ? Math.max(payload.expireAt - (payload.serverNow || Date.now()), 0) : null);\n if (remainingMs === null) {\n countdownEl.textContent = '--:--';\n return;\n }\n countdownEl.textContent = format(remainingMs);\n };\n update(state);\n if (state.eventsUrl) {\n const source = new EventSource(state.eventsUrl);\n source.onmessage = (event) => {\n try {\n update(JSON.parse(event.data));\n } catch {}\n };\n }\n })();\n <\/script>\n</body>\n</html>`;
8748
+ return `<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <title>临时预览</title>\n <style>\n * { box-sizing: border-box; }\n :root { --preview-bg: #ffffff; --preview-fg: #0f172a; --preview-muted: #64748b; }\n @media (prefers-color-scheme: dark) {\n :root { --preview-bg: #050505; --preview-fg: #e2e8f0; --preview-muted: #94a3b8; }\n }\n body { margin: 0; font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: var(--preview-bg); color: var(--preview-fg); }\n .preview-noise { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.25'/%3E%3C/svg%3E"); mix-blend-mode: soft-light; opacity: 0.8; }\n @media (max-width: 720px) {\n .max-w-6xl { padding-left: 16px; padding-right: 16px; }\n }\n </style>\n <style>${new HtmlWrapper(new ResourcePathManager()).getInlineStyles(path.join(process.cwd(), "video-preview.html"), false)}</style>\n</head>\n<body>\n <div id="app">${appHtml}</div>\n <script>\n window.__VIDEO_PREVIEW__=${serializedState};\n (() => {\n const state = window.__VIDEO_PREVIEW__ || {};\n const countdownEl = document.getElementById('preview-countdown');\n if (!countdownEl) return;\n const format = (ms) => {\n const totalSeconds = Math.max(Math.floor(ms / 1000), 0);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const pad = (value) => String(value).padStart(2, '0');\n return hours > 0 ? pad(hours) + ':' + pad(minutes) + ':' + pad(seconds) : pad(minutes) + ':' + pad(seconds);\n };\n const update = (payload) => {\n if (!payload.removeCache) {\n countdownEl.textContent = '不删除';\n return;\n }\n if (payload.removed) {\n countdownEl.textContent = '00:00';\n return;\n }\n const remainingMs = typeof payload.remainingMs === 'number'\n ? payload.remainingMs\n : (payload.expireAt ? Math.max(payload.expireAt - (payload.serverNow || Date.now()), 0) : null);\n if (remainingMs === null) {\n countdownEl.textContent = '--:--';\n return;\n }\n countdownEl.textContent = format(remainingMs);\n };\n update(state);\n if (state.eventsUrl) {\n const source = new EventSource(state.eventsUrl);\n source.onmessage = (event) => {\n try {\n update(JSON.parse(event.data));\n } catch {}\n };\n }\n })();\n <\/script>\n</body>\n</html>`;
8704
8749
  };
8705
8750
  var isSemverGreater = (remote, local) => {
8706
8751
  if (!remote || !local) return false;
@@ -8751,8 +8796,28 @@ var isSemverGreater = (remote, local) => {
8751
8796
  return false;
8752
8797
  };
8753
8798
  var import_qr_code_styling = __toESM(require_qr_code_styling(), 1);
8799
+ var createDomPurify = () => purify(new Window());
8800
+ var sanitizeValue = (value) => {
8801
+ const domPurify = createDomPurify();
8802
+ if (typeof value === "string") return domPurify.sanitize(value);
8803
+ if (Array.isArray(value)) return value.map((item) => sanitizeValue(item));
8804
+ if (value && typeof value === "object") {
8805
+ const output = {};
8806
+ for (const [key, item] of Object.entries(value)) output[key] = sanitizeValue(item);
8807
+ return output;
8808
+ }
8809
+ return value;
8810
+ };
8811
+ var createSanitizeContentPlugin = () => ({
8812
+ name: "数据消毒",
8813
+ enforce: "pre",
8814
+ beforeRender(ctx) {
8815
+ ctx.request.data = sanitizeValue(ctx.request.data);
8816
+ ctx.state.props = sanitizeValue(ctx.state.props);
8817
+ }
8818
+ });
8754
8819
  var createQrCodePlugin = () => ({
8755
- name: "qr-code",
8820
+ name: "生成二维码",
8756
8821
  enforce: "pre",
8757
8822
  async beforeRender(ctx) {
8758
8823
  const data = ctx.request.data || {};
@@ -8848,7 +8913,7 @@ var Render = async (event, path$1, data) => {
8848
8913
  }
8849
8914
  },
8850
8915
  outputDir,
8851
- plugins: [createQrCodePlugin()]
8916
+ plugins: [createQrCodePlugin(), createSanitizeContentPlugin()]
8852
8917
  }).then((res) => {
8853
8918
  if (!res.success || !res.htmlPath) throw new Error(res.error);
8854
8919
  return res;
@@ -8856,7 +8921,7 @@ var Render = async (event, path$1, data) => {
8856
8921
  throw new Error(`SSR渲染失败: ${err.message || "未知错误"}`);
8857
8922
  });
8858
8923
  const renderResult = await render.render({
8859
- name: `${Root.pluginName}/${templateType}/${templateName}`,
8924
+ name: `${Root.pluginName}/${templateType}`,
8860
8925
  file: result.htmlPath,
8861
8926
  multiPage: Config.app.multiPageRender ? Config.app.multiPageHeight : false,
8862
8927
  selector: "#container",
@@ -16602,18 +16667,42 @@ var DouYin = class DouYin extends Base {
16602
16667
  timeoutSeconds
16603
16668
  });
16604
16669
  await this.e.reply(img);
16670
+ logger.debug(`等待用户选择视频,开始计时,${timeoutSeconds}秒后终止等待...`);
16605
16671
  const context = await karin$1.ctx(this.e, {
16606
- reply: true,
16672
+ throwOnTimeout: false,
16607
16673
  time: timeoutSeconds
16608
16674
  });
16675
+ if (!context) {
16676
+ await this.e.reply(`${timeoutSeconds} 秒内没收到作品序号,已取消后续操作`);
16677
+ return true;
16678
+ }
16609
16679
  if (context) {
16610
16680
  const num = parseInt(context.msg.trim());
16611
16681
  if (!isNaN(num) && num >= 1 && num <= displayVideos.length) {
16612
- const targetData = {
16613
- type: "one_work",
16614
- aweme_id: displayVideos[num - 1].aweme_id
16615
- };
16616
- await new DouYin(context, targetData).DouyinHandler(targetData);
16682
+ const emojiManager = new EmojiReactionManager(context);
16683
+ let processingTimer = null;
16684
+ let successTimer = null;
16685
+ await emojiManager.add("EYES");
16686
+ processingTimer = setTimeout(() => {
16687
+ emojiManager.add("PROCESSING").catch(() => {});
16688
+ }, 1500);
16689
+ try {
16690
+ const targetData = {
16691
+ type: "one_work",
16692
+ aweme_id: displayVideos[num - 1].aweme_id
16693
+ };
16694
+ await new DouYin(context, targetData).DouyinHandler(targetData);
16695
+ successTimer = setTimeout(() => {
16696
+ emojiManager.replace("PROCESSING", "SUCCESS").catch(() => {});
16697
+ }, 1500);
16698
+ } catch (error) {
16699
+ if (processingTimer) clearTimeout(processingTimer);
16700
+ if (successTimer) clearTimeout(successTimer);
16701
+ const processingEmojiId = getEmojiId(context, "PROCESSING");
16702
+ if (emojiManager.has(processingEmojiId)) await emojiManager.remove("PROCESSING");
16703
+ await emojiManager.add("ERROR");
16704
+ throw error;
16705
+ }
16617
16706
  }
16618
16707
  }
16619
16708
  return true;
@@ -16682,7 +16771,7 @@ var DouYin = class DouYin extends Base {
16682
16771
  text: live_data.data.data[0].title,
16683
16772
  liveinf: `${live_data.data.partition_road_map.partition.title} | 房间号: ${room_data.owner.web_rid}`,
16684
16773
  "在线观众": Count(Number(live_data.data.data[0].room_view_stats?.display_value)),
16685
- "总观看次数": Count(Number(live_data.data.data[0].stats?.total_user_str)),
16774
+ "总观看次数": live_data.data.data[0].stats?.total_user_str ? Count(Number(live_data.data.data[0].stats?.total_user_str)) : "刚开播无法获取",
16686
16775
  username: UserInfoData.data.user.nickname,
16687
16776
  avater_url: UserInfoData.data.user.avatar_larger.url_list[0],
16688
16777
  fans: Count(UserInfoData.data.user.follower_count),
@@ -17246,19 +17335,21 @@ var DouYinpush = class extends Base {
17246
17335
  let iddata = { type: "one_work" };
17247
17336
  this.injectBotToEventForRender(pushItem.targets);
17248
17337
  if (!skip) iddata = await getDouyinID(this.e, Detail_Data.share_url ?? "https://live.douyin.com/" + Detail_Data.room_data?.owner.web_rid, false);
17249
- if (!skip) if (pushItem.pushType === "live" && "room_data" in pushItem.Detail_Data && Detail_Data.live_data) img = await Render(this.e, "douyin/live", {
17250
- image_url: Detail_Data.live_data.data.data.data[0]?.cover?.url_list[0] ?? Detail_Data.live_data.data.data.qrcode_url,
17251
- text: Detail_Data.live_data.data.data.data[0]?.title ?? "",
17252
- liveinf: `${Detail_Data.live_data.data.data.partition_road_map?.partition?.title ?? Detail_Data.live_data.data.data.data[0]?.title ?? "获取失败"} | 房间号: ${Detail_Data.room_data.owner.web_rid}`,
17253
- "在线观众": Detail_Data.live_data.data.data.data.length > 0 && Detail_Data.live_data.data.data.data[0].room_view_stats?.display_value ? this.count(Detail_Data.live_data.data.data.data[0].room_view_stats.display_value) : ":语音直播或刚开播获取失败。",
17254
- "总观看次数": Detail_Data.live_data.data.data.data.length > 0 ? this.count(Number(Detail_Data.live_data.data.data.data[0].stats.total_user_str)) : ":语音直播不支持",
17255
- username: Detail_Data.user_info.data.user.nickname,
17256
- avater_url: "https://p3-pc.douyinpic.com/aweme/1080x1080/" + Detail_Data.user_info.data.user.avatar_larger.uri,
17257
- fans: this.count(Detail_Data.user_info.data.user.follower_count),
17258
- share_url: "https://live.douyin.com/" + Detail_Data.room_data.owner.web_rid,
17259
- dynamicTYPE: "直播动态推送"
17260
- });
17261
- else {
17338
+ if (!skip) if (pushItem.pushType === "live" && "room_data" in pushItem.Detail_Data && Detail_Data.live_data) {
17339
+ const hasData = Detail_Data.live_data.data && Detail_Data.live_data.data.data && Detail_Data.live_data.data.data.length > 0;
17340
+ img = await Render(this.e, "douyin/live", {
17341
+ image_url: Detail_Data.live_data.data.data.data[0]?.cover?.url_list[0] ?? Detail_Data.live_data.data.data.qrcode_url,
17342
+ text: Detail_Data.live_data.data.data.data[0]?.title ?? "",
17343
+ liveinf: `${Detail_Data.live_data.data.data.partition_road_map?.partition?.title ?? Detail_Data.live_data.data.data.data[0]?.title ?? "获取失败"} | 房间号: ${Detail_Data.room_data.owner.web_rid}`,
17344
+ "在线观众": hasData && Detail_Data.live_data.data.data.data[0].room_view_stats?.display_value ? this.count(Detail_Data.live_data.data.data.data[0].room_view_stats.display_value) : ":语音直播或刚开播获取失败。",
17345
+ "总观看次数": hasData ? Detail_Data.live_data.data.data.data[0].stats?.total_user_str ? this.count(Number(Detail_Data.live_data.data.data.data[0].stats.total_user_str)) : "刚开播无法获取" : ":语音直播不支持",
17346
+ username: Detail_Data.user_info.data.user.nickname,
17347
+ avater_url: "https://p3-pc.douyinpic.com/aweme/1080x1080/" + Detail_Data.user_info.data.user.avatar_larger.uri,
17348
+ fans: this.count(Detail_Data.user_info.data.user.follower_count),
17349
+ share_url: "https://live.douyin.com/" + Detail_Data.room_data.owner.web_rid,
17350
+ dynamicTYPE: "直播动态推送"
17351
+ });
17352
+ } else {
17262
17353
  const realUrl = Config.douyin.push.shareType === "web" && await new Network({
17263
17354
  url: Detail_Data.share_url,
17264
17355
  headers: {
@@ -18463,7 +18554,7 @@ var handleCacheCleanup = wrapWithErrorHandler(async () => {
18463
18554
  logger.mark(`${Common.tempDri.images} 目录下已删除 ${imageDeleted} 个文件`);
18464
18555
  }
18465
18556
  }, { businessName: "缓存自动删除" });
18466
- var task = Config.app.removeCache && karin$1.task("[kkk-缓存自动删除]", "0 */4 * * *", handleCacheCleanup);
18557
+ var task = Config.app.removeCache && karin$1.task("[kkk-缓存自动删除]", "*/30 * * * *", handleCacheCleanup);
18467
18558
  var handleBilibiliLogin = wrapWithErrorHandler(async (e) => {
18468
18559
  await bilibiliLogin(e);
18469
18560
  return true;
@@ -18489,7 +18580,7 @@ var removeOldFiles = (dir, beforeTimestamp) => {
18489
18580
  if (stats.isDirectory()) {
18490
18581
  deletedCount += removeOldFiles(filePath, beforeTimestamp);
18491
18582
  if (fs.readdirSync(filePath).length === 0) fs.rmdirSync(filePath);
18492
- } else if (stats.mtimeMs < beforeTimestamp) {
18583
+ } else if (stats.birthtimeMs < beforeTimestamp) {
18493
18584
  fs.unlinkSync(filePath);
18494
18585
  deletedCount++;
18495
18586
  }
@@ -23068,7 +23159,7 @@ app$1.get("/video/:filename", getVideoRouter);
23068
23159
  app$1.get("/video/:filename/events", videoPreviewEventsRouter);
23069
23160
  app$1.use("/v1", apiRouter);
23070
23161
  app.use("/api/kkk", app$1);
23071
- var requireVersion = "1.15.0";
23162
+ var requireVersion = "1.15.2";
23072
23163
  if (process.env.NODE_ENV !== "development" && isSemverGreater(requireVersion, Root.karinVersion)) {
23073
23164
  const msg = `[karin-plugin-kkk] 插件构建时的 karin 版本 (${requireVersion}) 高于当前运行版本 (${Root.karinVersion}),可能会出现兼容性问题!`;
23074
23165
  logger.warn(msg);
@@ -35676,4 +35767,4 @@ var XiaohongshuNoteInfo = import_react.memo((props) => {
35676
35767
  });
35677
35768
  });
35678
35769
  XiaohongshuNoteInfo.displayName = "XiaohongshuNoteInfo";
35679
- export { setdyPush as $, BilibiliVideoDynamic as A, kuaishouAPP as B, DouyinArticleWork as C, bilibiliFetcher as Ct, BilibiliLiveDynamic as D, Root as Dt, BilibiliWordDynamic as E, reloadAmagiConfig as Et, kkkUpdate as F, qrLogin as G, xiaohongshuAPP as H, kkkUpdateCommand as I, changeBotID as J, bilibiliPush as K, update as L, BangumiBilibili as M, BilibiliUserList as N, BilibiliForwardDynamic as O, BilibiliComment as P, setbiliPush as Q, bilibiliAPP as R, DouyinComment as S, AmagiError as St, BilibiliQrcodeImg as T, kuaishouFetcher as Tt, globalStatistics as U, prefix as V, groupStatistics as W, douyinPushList as X, douyinPush as Y, forcePush as Z, DouyinMusicInfo as _, DouyinDBBase as _t, Changelog as a, removeOldFiles as at, DouyinFavoriteList as b, renderVideoPreviewPage as bt, GroupStatistics as c, webConfig as ct, DouyinVideoInfo as d, douyinDBInstance as dt, testDouyinPush as et, DouyinQrcodeImg as f, getBilibiliDB as ft, DouyinRecommendList as g, StatisticsDBBase as gt, DouyinUserList as h, initAllDatabases as ht, handlerError as i, dylogin as it, BilibiliArticleDynamic as j, BilibiliDrawDynamic as k, GlobalStatistics as l, bilibiliDBInstance as lt, DouyinUserVideoList as m, getStatisticsDB as mt, XiaohongshuComment as n, version as nt, VersionWarning as o, task as ot, DouyinVideoWork as p, getDouyinDB as pt, bilibiliPushList as q, QrLogin as r, biLogin as rt, Help as s, template_default as st, XiaohongshuNoteInfo as t, help as tt, KuaishouComment as u, cleanOldDynamicCache as ut, DouyinLive as v, BilibiliDBBase as vt, BilibiliVideoInfo as w, douyinFetcher as wt, DouyinDynamic as x, AmagiBase as xt, DouyinImageWork as y, reactServerRender as yt, douyinAPP as z };
35770
+ export { setdyPush as $, BilibiliVideoDynamic as A, kuaishouAPP as B, DouyinArticleWork as C, amagiClient as Ct, BilibiliLiveDynamic as D, reloadAmagiConfig as Dt, BilibiliWordDynamic as E, kuaishouFetcher as Et, kkkUpdate as F, qrLogin as G, xiaohongshuAPP as H, kkkUpdateCommand as I, changeBotID as J, bilibiliPush as K, update as L, BangumiBilibili as M, BilibiliUserList as N, BilibiliForwardDynamic as O, Root as Ot, BilibiliComment as P, setbiliPush as Q, bilibiliAPP as R, DouyinComment as S, AmagiError as St, BilibiliQrcodeImg as T, douyinFetcher as Tt, globalStatistics as U, prefix as V, groupStatistics as W, douyinPushList as X, douyinPush as Y, forcePush as Z, DouyinMusicInfo as _, DouyinDBBase as _t, Changelog as a, removeOldFiles as at, DouyinFavoriteList as b, renderVideoPreviewPage as bt, GroupStatistics as c, webConfig as ct, DouyinVideoInfo as d, douyinDBInstance as dt, testDouyinPush as et, DouyinQrcodeImg as f, getBilibiliDB as ft, DouyinRecommendList as g, StatisticsDBBase as gt, DouyinUserList as h, initAllDatabases as ht, handlerError as i, dylogin as it, BilibiliArticleDynamic as j, BilibiliDrawDynamic as k, GlobalStatistics as l, bilibiliDBInstance as lt, DouyinUserVideoList as m, getStatisticsDB as mt, XiaohongshuComment as n, version as nt, VersionWarning as o, task as ot, DouyinVideoWork as p, getDouyinDB as pt, bilibiliPushList as q, QrLogin as r, biLogin as rt, Help as s, template_default as st, XiaohongshuNoteInfo as t, help as tt, KuaishouComment as u, cleanOldDynamicCache as ut, DouyinLive as v, BilibiliDBBase as vt, BilibiliVideoInfo as w, bilibiliFetcher as wt, DouyinDynamic as x, AmagiBase as xt, DouyinImageWork as y, reactServerRender as yt, douyinAPP as z };
@@ -0,0 +1,2 @@
1
+ import { t as XiaohongshuNoteInfo } from "./main-6Y7nyjx4.js";
2
+ export { XiaohongshuNoteInfo, XiaohongshuNoteInfo as default };
@@ -0,0 +1,2 @@
1
+ import { T as BilibiliQrcodeImg } from "./main-6Y7nyjx4.js";
2
+ export { BilibiliQrcodeImg, BilibiliQrcodeImg as default };
@@ -0,0 +1,2 @@
1
+ import { f as DouyinQrcodeImg } from "./main-6Y7nyjx4.js";
2
+ export { DouyinQrcodeImg, DouyinQrcodeImg as default };
@@ -0,0 +1,2 @@
1
+ import { r as QrLogin } from "./main-6Y7nyjx4.js";
2
+ export { QrLogin, QrLogin as default };
@@ -0,0 +1,2 @@
1
+ import "./main-6Y7nyjx4.js";
2
+ export {};
@@ -331,28 +331,28 @@ type VideoListItem = {
331
331
  duration: number; /** 创建时间戳 */
332
332
  create_time: number; /** 统计数据 */
333
333
  statistics: {
334
- like_count: number;
335
- comment_count: number;
336
- share_count: number;
334
+ /** 点赞数 */like_count: number; /** 评论数 */
335
+ comment_count: number; /** 分享数 */
336
+ share_count: number; /** 收藏数 */
337
337
  collect_count: number;
338
338
  }; /** 是否为视频(true)还是图集(false) */
339
339
  is_video: boolean; /** 背景音乐信息 */
340
340
  music?: {
341
- title: string;
341
+ /** 音乐标题 */title: string; /** 音乐作者 */
342
342
  author: string;
343
343
  };
344
344
  };
345
345
  type UserVideoListData = {
346
346
  /** 用户基本信息 */user: {
347
- head_image: string | null;
348
- nickname: string;
349
- short_id: string;
350
- avatar: string;
351
- signature: string;
352
- follower_count: number;
353
- following_count: number;
354
- total_favorited: number;
355
- verified: boolean;
347
+ /** 头像图片(可能为 null) */head_image: string | null; /** 用户昵称 */
348
+ nickname: string; /** 抖音号 */
349
+ short_id: string; /** 头像URL */
350
+ avatar: string; /** 用户签名/简介 */
351
+ signature: string; /** 粉丝数 */
352
+ follower_count: number; /** 关注数 */
353
+ following_count: number; /** 获赞总数 */
354
+ total_favorited: number; /** 是否认证 */
355
+ verified: boolean; /** IP属地 */
356
356
  ip_location: string;
357
357
  }; /** 视频列表 */
358
358
  videos: VideoListItem[]; /** 超时秒数 */
@@ -1,3 +1,2 @@
1
- import { bt as renderVideoPreviewPage, st as template_default, yt as reactServerRender } from "./main-6QQJ5H3C.js";
2
- import "./vendor-CupLbLdw.js";
1
+ import { bt as renderVideoPreviewPage, st as template_default, yt as reactServerRender } from "./main-6Y7nyjx4.js";
3
2
  export { template_default as default, reactServerRender, renderVideoPreviewPage };