0x3f-problem-solution

自定义分数区间显示题目 标记题目状态 配合灵茶山艾府题单解题

As of 2025-03-04. See the latest version.

  1. // ==UserScript==
  2. // @name 0x3f-problem-solution
  3. // @namespace https://greatest.deepsurf.us//zh-CN/scripts/501134-0x3f-problem-solution
  4. // @version 0.0.5.5
  5. // @author wuxin0011
  6. // @description 自定义分数区间显示题目 标记题目状态 配合灵茶山艾府题单解题
  7. // @license MIT
  8. // @icon https://assets.leetcode.cn/aliyun-lc-upload/users/endlesscheng/avatar_1690721039.png
  9. // @source https://github.com/wuxin0011/tampermonkey-script/tree/main/0x3f-leetcode
  10. // @supportURL https://greatest.deepsurf.us//zh-CN/scripts/501134-0x3f-problem-solution/feedback
  11. // @match https://leetcode.cn/circle/discuss/*
  12. // @match https://leetcode.cn/discuss/*
  13. // @match https://leetcode.cn/problems/*
  14. // @match https://leetcode.cn/contest/*/problems/*
  15. // @match https://leetcode.com/circle/discuss/*
  16. // @match https://leetcode.com/discuss/*
  17. // @match https://leetcode.com/problems/*
  18. // @match https://leetcode.com/contest/*/problems/*
  19. // @require https://unpkg.com/vue@3.4.31/dist/vue.global.prod.js
  20. // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
  21. // @require https://unpkg.com/element-plus@2.7.6/dist/index.full.js
  22. // @resource elementPlusCss https://unpkg.com/element-plus@2.7.6/dist/index.css
  23. // @grant GM_addStyle
  24. // @grant GM_deleteValue
  25. // @grant GM_getResourceText
  26. // @grant GM_getValue
  27. // @grant GM_registerMenuCommand
  28. // @grant GM_setValue
  29. // ==/UserScript==
  30.  
  31. (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const n=document.createElement("style");n.textContent=t,document.head.append(n)})(" h2[data-v-6b5a9c54]{color:#000!important;margin:10px 0!important;font-size:20px!important}.m-setting-button[data-v-76dd1ba0]{position:fixed;top:200px;right:0;z-index:100000}.m-button[data-v-76dd1ba0]{margin-left:16px!important;padding:5px!important;font-size:14px!important}.processs-flex[data-v-76dd1ba0]{display:flex;justify-content:center;align-items:center}.m-setting-button[data-v-6868725a]{position:fixed;top:200px;right:0;z-index:100000}.m-button[data-v-6868725a]{margin-left:16px!important;padding:5px!important;font-size:14px!important}.processs-flex[data-v-6868725a]{display:flex;justify-content:center;align-items:center} ");
  32.  
  33. (function (ElementPlus, vue) {
  34. 'use strict';
  35.  
  36. var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
  37. var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
  38. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  39. var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  40. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  41. let Cache$1 = class Cache2 {
  42. set(k, v) {
  43. _GM_setValue(k, v);
  44. }
  45. get(k, parse = true, name = String.name) {
  46. try {
  47. let v = _GM_getValue(k);
  48. switch (name) {
  49. case String.name:
  50. if (v == null) {
  51. return "null";
  52. }
  53. return v;
  54. case Object.name:
  55. if (v == null || v == void 0 || typeof v != "object") {
  56. return {};
  57. }
  58. return v;
  59. case Boolean.name:
  60. if (v === null || v == void 0) {
  61. return false;
  62. }
  63. if (v == false || v == "false" || v == "" || v == "null") {
  64. return false;
  65. }
  66. return v;
  67. case Array.name:
  68. if (v === null || v == void 0 || !Array.isArray(v)) {
  69. return [];
  70. }
  71. return v;
  72. default:
  73. return v;
  74. }
  75. } catch (E) {
  76. return null;
  77. }
  78. }
  79. remove(k) {
  80. _GM_deleteValue(k);
  81. }
  82. };
  83. const Cache$2 = new Cache$1();
  84. const width = 14;
  85. const height = 14;
  86. const svg_css_style = () => isEnglishENV() ? "" : document.querySelector('#lc-content [class*="CollapsibleMarkdownContent"] [class*="MarkdownContent"]') ? ` ` : "display:inline;margin-bottom:3px;";
  87. const bilibiliSVG = () => {
  88. return `<svg width="${width}px" height="${height}px" style="${svg_css_style()}" status="bilibili" title="bilibili" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#00a3d9">
  89. <path fill="none" d="M0 0h24v24H0z"></path>
  90. <path d="M18.223 3.086a1.25 1.25 0 0 1 0 1.768L17.08 5.996h1.17A3.75 3.75 0 0 1 22 9.747v7.5a3.75 3.75 0 0 1-3.75 3.75H5.75A3.75 3.75 0 0 1 2 17.247v-7.5a3.75 3.75 0 0 1 3.75-3.75h1.166L5.775 4.855a1.25 1.25 0 1 1 1.767-1.768l2.652 2.652q.119.119.198.257h3.213q.08-.14.199-.258l2.651-2.652a1.25 1.25 0 0 1 1.768 0m.027 5.42H5.75a1.25 1.25 0 0 0-1.247 1.157l-.003.094v7.5c0 .659.51 1.199 1.157 1.246l.093.004h12.5a1.25 1.25 0 0 0 1.247-1.157l.003-.093v-7.5c0-.69-.56-1.25-1.25-1.25zm-10 2.5c.69 0 1.25.56 1.25 1.25v1.25a1.25 1.25 0 1 1-2.5 0v-1.25c0-.69.56-1.25 1.25-1.25m7.5 0c.69 0 1.25.56 1.25 1.25v1.25a1.25 1.25 0 1 1-2.5 0v-1.25c0-.69.56-1.25 1.25-1.25"></path>
  91. </svg>
  92. `;
  93. };
  94. const problemContenst = () => `
  95. <svg width="${width}px" height="${height}px" style="${svg_css_style()}" status="contest" title="竞赛题目专属图标" viewBox="-3.5 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
  96. <path d="M9.73795 18.8436L12.9511 20.6987L6.42625 32L4.55349 27.8233L9.73795 18.8436Z" fill="#CE4444"/>
  97. <path d="M9.73795 18.8436L6.52483 16.9885L0 28.2898L4.55349 27.8233L9.73795 18.8436Z" fill="#983535"/>
  98. <path d="M14.322 18.8436L11.1088 20.6987L17.6337 32L19.5064 27.8233L14.322 18.8436Z" fill="#983535"/>
  99. <path d="M14.322 18.8436L17.5351 16.9885L24.0599 28.2898L19.5064 27.8233L14.322 18.8436Z" fill="#CE4444"/>
  100. <path d="M22.9936 11.0622C22.9936 17.1716 18.0409 22.1243 11.9314 22.1243C5.82194 22.1243 0.869249 17.1716 0.869249 11.0622C0.869249 4.9527 5.82194 0 11.9314 0C18.0409 0 22.9936 4.9527 22.9936 11.0622Z" fill="url(#paint0_linear_103_1801)"/>
  101. <path d="M20.5665 11.0621C20.5665 15.8311 16.7004 19.6972 11.9315 19.6972C7.16247 19.6972 3.29645 15.8311 3.29645 11.0621C3.29645 6.29315 7.16247 2.42713 11.9315 2.42713C16.7004 2.42713 20.5665 6.29315 20.5665 11.0621Z" fill="#A88300"/>
  102. <path d="M21.0477 11.984C21.0477 16.7641 17.1727 20.6391 12.3926 20.6391C7.61251 20.6391 3.73748 16.7641 3.73748 11.984C3.73748 7.20389 7.61251 3.32887 12.3926 3.32887C17.1727 3.32887 21.0477 7.20389 21.0477 11.984Z" fill="#C28B37"/>
  103. <path d="M20.5868 11.0621C20.5868 15.8422 16.7118 19.7172 11.9317 19.7172C7.15159 19.7172 3.27656 15.8422 3.27656 11.0621C3.27656 6.28205 7.15159 2.40702 11.9317 2.40702C16.7118 2.40702 20.5868 6.28205 20.5868 11.0621Z" fill="#C09525"/>
  104. <path d="M11.9781 5.04096L13.8451 8.77502L17.5792 9.24178L15.0151 12.117L15.7122 16.2431L11.9781 14.3761L8.24404 16.2431L8.94729 12.117L6.37701 9.24178L10.1111 8.77502L11.9781 5.04096Z" fill="url(#paint1_linear_103_1801)"/>
  105. <defs>
  106. <linearGradient id="paint0_linear_103_1801" x1="11.1804" y1="4.03192" x2="12.6813" y2="31.965" gradientUnits="userSpaceOnUse">
  107. <stop stop-color="#FFC600"/>
  108. <stop offset="1" stop-color="#FFDE69"/>
  109. </linearGradient>
  110. <linearGradient id="paint1_linear_103_1801" x1="11.9783" y1="5.04096" x2="11.9783" y2="16.2431" gradientUnits="userSpaceOnUse">
  111. <stop stop-color="#FFFCDD"/>
  112. <stop offset="1" stop-color="#FFE896"/>
  113. </linearGradient>
  114. </defs>
  115. </svg>
  116.  
  117. `;
  118. const problemFinsh = () => `
  119.  
  120. <svg width="${width}px" height="${height}px" style="${svg_css_style()}" status="ac" title="AC专属图标" viewBox="0 0 1024 1024" version="1.1"
  121. xmlns="http://www.w3.org/2000/svg">
  122. <path d="M512 512m-448 0a448 448 0 1 0 896 0 448 448 0 1 0-896 0Z" fill="#4CAF50" />
  123. <path
  124. d="M738.133333 311.466667L448 601.6l-119.466667-119.466667-59.733333 59.733334 179.2 179.2 349.866667-349.866667z"
  125. fill="#CCFF90" />
  126. </svg>
  127.  
  128. `;
  129. const problemsTry = () => `
  130. <svg width="${width}px" height="${height}px" style="${svg_css_style()}" status="notac" title="尝试过" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
  131. xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512"
  132. style="enable-background:new 0 0 512 512;" xml:space="preserve">
  133. <path style="fill:#FEDEA1;" d="M256,12.8C121.899,12.8,12.8,121.899,12.8,256S121.899,499.2,256,499.2S499.2,390.101,499.2,256
  134. S390.101,12.8,256,12.8z" />
  135. <g>
  136. <path style="fill:#573A32;" d="M256,115.2c-49.271,0-92.561,25.353-117.726,63.676l18.859,18.859
  137. C177.178,163.806,213.734,140.8,256,140.8c63.625,0,115.2,51.567,115.2,115.2h-38.4l51.2,51.2l51.2-51.2h-38.4
  138. C396.8,178.244,333.764,115.2,256,115.2z" />
  139. <path style="fill:#573A32;" d="M256,0C114.62,0,0,114.62,0,256s114.62,256,256,256s256-114.62,256-256S397.38,0,256,0z M256,486.4
  140. C128.956,486.4,25.6,383.044,25.6,256S128.956,25.6,256,25.6S486.4,128.956,486.4,256S383.044,486.4,256,486.4z" />
  141. <path style="fill:#573A32;" d="M256,371.2c-63.625,0-115.2-51.567-115.2-115.2h38.4L128,204.8L76.8,256h38.4
  142. c0,77.756,63.036,140.8,140.8,140.8c49.272,0,92.561-25.353,117.726-63.676l-18.859-18.859
  143. C334.822,348.194,298.266,371.2,256,371.2z" />
  144. </g>
  145. </svg>
  146.  
  147. `;
  148. const problemsNo = () => install_pos() ? `
  149. <svg width="${width}px" height="${height}px" style="${svg_css_style()}" status="null" title="未尝试" viewBox="0 0 24 24" id="meteor-icon-kit__regular-circle" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12Z" fill="#758CA3"/></svg>
  150. ` : ``;
  151. const createStatus = (status, link) => {
  152. var _a;
  153. let node;
  154. if (!link) {
  155. return;
  156. }
  157. const curUrl = (link == null ? void 0 : link.href) ?? ((_a = link.querySelector("a")) == null ? void 0 : _a.href);
  158. node = link instanceof HTMLAnchorElement ? link.parentElement : link;
  159. if (node) {
  160. node.status = status;
  161. }
  162. let installSVG = "";
  163. if (isContest(curUrl)) {
  164. installSVG = problemContenst();
  165. } else if (isLeetCodeCircleUrl(curUrl)) ;
  166. else if (isBilibili(curUrl)) {
  167. installSVG = bilibiliSVG();
  168. } else {
  169. if (status == STATUS["AC"]) {
  170. installSVG = problemFinsh();
  171. } else if (status == STATUS["notac"]) {
  172. installSVG = problemsTry();
  173. } else if (status == STATUS["NO"]) {
  174. installSVG = problemsNo();
  175. }
  176. }
  177. let svg = node.querySelector("svg");
  178. if (svg) {
  179. if (svg.getAttribute("status") == status || svg.getAttribute("status") == STATUS["AC"]) {
  180. return false;
  181. }
  182. svg.remove();
  183. }
  184. if (isBilibili(curUrl)) {
  185. node.innerHTML = node.innerHTML + "&nbsp;" + installSVG;
  186. } else {
  187. node.innerHTML = install_pos() ? installSVG + node.innerHTML : node.innerHTML + installSVG;
  188. }
  189. return true;
  190. };
  191. const inf = 4e3;
  192. const mi = 1e3;
  193. const __0X3F_PROBLEM_KEYS__$1 = {
  194. "__0x3f_problmes_solution__": "__0x3f_problmes_solution__",
  195. // 基本信息
  196. "__0x3f_problmes_urls__": "__0x3f_problmes_urls__",
  197. // 题单key
  198. "__0x3f_problmes_update__": "__0x3f_problmes_update__",
  199. // 是否修改了默认题单key
  200. "__0x3f_problmes_button_is_none__": "__is_none_0x3f_problmes_button__",
  201. // 是否隐藏设置按钮
  202. "__0x3f_problmes_insert_pos__": "__0x3f_problmes_insert_pos__",
  203. // 安装位置
  204. "__0x3f_problmes_status_update__": "__0x3f_problmes_status_update__",
  205. "__0x3f_problmes_plugin_load_ok__": "__0x3f_problmes_plugin_load_ok__",
  206. // 是否使用插件
  207. "__0x3f_problmes_add_cur__": "__0x3f_problmes_add_cur__",
  208. // 添加 url
  209. "__0x3f_problmes_ac_key__": "__local_ok_problem_key__",
  210. // ac key
  211. "__0x3f_problmes_ac_version__": "__0x3f_problmes_ac_version__",
  212. // TODO ac key version
  213. "__0x3f_problmes_all_problems__": "__0x3f_problmes_all_problems__",
  214. // all problems
  215. "__0x3f_problmes_random_problems_key__": "__0x3f_problmes_random_problems_key__",
  216. //随机题目快捷键
  217. "__0x3f_problmes_random_problems__": "__0x3f_problmes_random_problems__",
  218. //随机题目
  219. "__0x3f_problme_support_type__": "__0x3f_problme_support_type__",
  220. //是否替换到com 默认cn
  221. "__0x3f_problme_support_type_tips__": "__0x3f_problme_support_type_tips__",
  222. //是否替换到com 默认cn 不再提示key
  223. "__0x3f_problme_stop_discuss_": "__0x3f_problme_stop_discuss_"
  224. //屏蔽讨论区
  225. };
  226. const STATUS = {
  227. "AC": "ac",
  228. "NO": "null",
  229. "notac": "notac",
  230. "Accepted": "ac",
  231. "Wrong Answer": "notac"
  232. };
  233. const defaultObj = {
  234. min: mi,
  235. max: inf,
  236. visiableMember: true,
  237. onlyUrls: false,
  238. useDefaultSetting: true,
  239. hiddenAc: false,
  240. showAcConfig: true,
  241. sortedType: 0
  242. };
  243. function install_pos() {
  244. return !Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_insert_pos__"], false, Boolean.name);
  245. }
  246. function isShow(text, min, max) {
  247. if (!text) {
  248. return true;
  249. }
  250. let res = text.match(/\d+/ig);
  251. if (!res) {
  252. return true;
  253. }
  254. if (Array.isArray(res) && res.length < 2) {
  255. return true;
  256. }
  257. let s = 0;
  258. for (let i = res.length - 1; i >= 0; i--) {
  259. s = res[i];
  260. if (s >= mi && s <= inf) {
  261. return s >= min && s <= max;
  262. }
  263. }
  264. return true;
  265. }
  266. let A = void 0;
  267. const linkCssSelector_pre = () => isEnglishENV() ? ".discuss-markdown-container" : document.querySelector('#lc-content [class*="CollapsibleMarkdownContent"] [class*="MarkdownContent"]') ? `#lc-content [class*="CollapsibleMarkdownContent"] [class*="MarkdownContent"]` : `.break-words`;
  268. const linkCssSelector = `${linkCssSelector_pre()} li>a`;
  269. const queryProblem = () => Array.from(document.querySelectorAll(linkCssSelector)).filter((item) => item && item instanceof HTMLAnchorElement && (isProblem(item.href) || isContest(item.href)));
  270. function loadProblems() {
  271. A = queryProblem();
  272. return A;
  273. }
  274. function handlerProblem(data) {
  275. var _a;
  276. try {
  277. loadProblems();
  278. let { min, max, visiableMember, useDefaultSetting, onlyUrls, hiddenAc } = data;
  279. if (isNaN(min) || isNaN(max)) {
  280. min = mi;
  281. max = inf;
  282. }
  283. if (min < mi) {
  284. min = mi;
  285. }
  286. if (max < min) {
  287. max = inf;
  288. }
  289. min = Number(min);
  290. max = Number(max);
  291. data.min = min;
  292. data.max = max;
  293. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_solution__"], data);
  294. for (let i = 0; i < A.length; i++) {
  295. if (!(A[i] instanceof HTMLAnchorElement)) {
  296. continue;
  297. }
  298. let d = (_a = A[i]) == null ? void 0 : _a.parentNode;
  299. if (!d) {
  300. continue;
  301. }
  302. let none = false;
  303. let Nohidden = isShow(d.textContent, min, max);
  304. d.style.display = Nohidden ? "" : "none";
  305. if (!Nohidden) {
  306. continue;
  307. }
  308. if (hiddenAc) {
  309. const svg = d.querySelector("svg");
  310. if (svg && svg.getAttribute("status")) {
  311. d.style.display = svg.getAttribute("status") == STATUS["AC"] ? "none" : "";
  312. }
  313. } else {
  314. d.style.display = "";
  315. }
  316. let c = d.textContent && d.textContent.indexOf("会员") != -1;
  317. if (!c) {
  318. continue;
  319. }
  320. d.style.display = visiableMember ? "" : "none";
  321. }
  322. } catch (e) {
  323. console.log("error", e);
  324. }
  325. }
  326. function computeAcInfo(saveUrls = [], deleteOk = true) {
  327. let infos = [];
  328. let set = /* @__PURE__ */ new Set();
  329. for (let i = 0, u = null; Array.isArray(saveUrls) && i < saveUrls.length; i++) {
  330. try {
  331. u = saveUrls[i];
  332. if (!(u == null ? void 0 : u.link) || !(u == null ? void 0 : u.title) || !(u == null ? void 0 : u.id) || set.has(u.link)) {
  333. continue;
  334. }
  335. if (u["select"] == void 0) u.select = true;
  336. if (u["loading"] == void 0 || u["loading"]) u["loading"] = false;
  337. let s = Object.values(u).join("");
  338. if (s == "null" || !Cache$2.get(u.link) || !getAcCountKey(u.link) || !Cache$2.get(getAcCountKey(u.link))) {
  339. continue;
  340. }
  341. let o = Cache$2.get(getAcCountKey(u.link));
  342. u["ac"] = isNaN(o["ac"]) ? 0 : parseInt(o["ac"]);
  343. u["tot"] = isNaN(o["tot"]) ? 0 : parseInt(o["tot"]);
  344. set.add(u.link);
  345. } catch (e) {
  346. }
  347. infos.push(Object.assign({}, u));
  348. }
  349. if (deleteOk) {
  350. for (let i = 0; i < saveUrls[i]; i++) {
  351. delete saveUrls[i];
  352. }
  353. for (let info of infos) {
  354. saveUrls.push(info);
  355. }
  356. }
  357. return infos;
  358. }
  359. const initUrls = () => {
  360. let saveUrls = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_update__"], true, Boolean.name) ? Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_urls__"], true, Array.name) : defaultUrls;
  361. return computeAcInfo(saveUrls);
  362. };
  363. const initObj = () => {
  364. let obj = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_solution__"]) ? Object.assign(defaultObj, Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_solution__"])) : defaultObj;
  365. if (obj["showAcConfig"] == null || obj["showAcConfig"] == void 0) {
  366. obj.showAcConfig = true;
  367. }
  368. if (obj["sortedType"] == null || obj["sortedType"] == void 0) {
  369. obj.sortedType = 0;
  370. }
  371. let temp = {};
  372. for (let key of Object.keys(obj)) {
  373. if (!isNaN(key) || defaultObj[`${key}`] == void 0) continue;
  374. temp[`${key}`] = obj[`${key}`];
  375. }
  376. return temp;
  377. };
  378. const support_plugins = () => {
  379. const u = initObj();
  380. if (!u || !u.onlyUrls) return true;
  381. let url = window.location.href;
  382. if (isLeetCodeCircleUrl(url) && url.indexOf("view") != -1) {
  383. try {
  384. url = url.split("view")[0];
  385. } catch (e) {
  386. url = window.location.href;
  387. }
  388. }
  389. const urls = initUrls();
  390. for (let info of urls) {
  391. if (!info || !(info == null ? void 0 : info.link)) {
  392. continue;
  393. }
  394. if (info.link.indexOf(url) != -1) {
  395. return true;
  396. }
  397. }
  398. return false;
  399. };
  400. const defaultUrls = [
  401. { "title": "数学算法(数论/组合/概率期望/博弈/计算几何/随机算法", "link": "https://leetcode.cn/circle/discuss/IYT3ss/", "tot": 0, "ac": 0, "id": 1, "disabled": false, "select": true },
  402. { "title": "常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)", "link": "https://leetcode.cn/circle/discuss/mOr1u6/", "tot": 0, "ac": 0, "id": 2, "disabled": false, "select": true },
  403. { "title": "动态规划(入门/背包/状态机/划分/区间/状压/数位/树形/数据结构优化)", "link": "https://leetcode.cn/circle/discuss/tXLS3i/", "tot": 0, "ac": 0, "id": 3, "disabled": false, "select": true },
  404. { "title": "图论算法(DFS/BFS/拓扑排序/最短路/最小生成树/二分图/基环树/欧拉路径)", "link": "https://leetcode.cn/circle/discuss/01LUak/", "tot": 0, "ac": 0, "id": 4, "disabled": false, "select": true },
  405. { "title": "位运算(基础/性质/拆位/试填/恒等式/贪心/脑筋急转弯)", "link": "https://leetcode.cn/circle/discuss/dHn9Vk/", "tot": 0, "ac": 0, "id": 5, "disabled": false, "select": true },
  406. { "title": "网格图(DFS/BFS/综合应用)", "link": "https://leetcode.cn/circle/discuss/YiXPXW/", "tot": 0, "ac": 0, "id": 6, "disabled": false, "select": true },
  407. { "title": "单调栈(矩形面积/贡献法/最小字典序", "link": "https://leetcode.cn/circle/discuss/9oZFK9/", "tot": 0, "ac": 0, "id": 7, "disabled": false, "select": true },
  408. { "title": "二分算法(二分答案/最小化最大值/最大化最小值/第K小", "link": "https://leetcode.cn/circle/discuss/SqopEo/", "tot": 0, "ac": 0, "id": 8, "disabled": true, "select": true },
  409. { "title": "滑动窗口(定长/不定长/多指针", "link": "https://leetcode.cn/circle/discuss/0viNMK/", "tot": 0, "ac": 0, "id": 9, "disabled": false, "select": true },
  410. { "title": "贪心算法(基本贪心策略/反悔/区间/字典序/数学/思维/构造)", "link": "https://leetcode.cn/circle/discuss/g6KTKL/", "tot": 0, "ac": 0, "id": 10, "disabled": false, "select": true },
  411. { "title": "链表、二叉树与一般树(前后指针/快慢指针/DFS/BFS/直径/LCA)", "link": "https://leetcode.cn/circle/discuss/K0n2gO/", "tot": 0, "ac": 0, "id": 11, "disabled": false, "select": true },
  412. { "title": "字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)", "link": "https://leetcode.cn/circle/discuss/SJFwQI/", "tot": 0, "ac": 0, "id": 12, "disabled": false, "select": true }
  413. // { 'title': '灵茶题单完成情况', 'link': 'https://leetcode.cn/u/endlesscheng/', 'tot': 0, 'ac': 0, 'id': 0x3f3f3f3f,'disabled':true,'select':false },
  414. ];
  415. function getId(problemUrl) {
  416. if (isContest(problemUrl) || isProblem(problemUrl)) {
  417. try {
  418. return problemUrl.split("problems")[1].split("/")[1];
  419. } catch (e) {
  420. return "";
  421. }
  422. }
  423. return "";
  424. }
  425. function postData(ID2) {
  426. return {
  427. "query": "\n query userQuestionStatus($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n status\n }\n}\n ",
  428. "variables": {
  429. "titleSlug": ID2
  430. },
  431. "operationName": "userQuestionStatus"
  432. };
  433. }
  434. async function queryStatus(ID2 = "", cache = {}, cur = void 0, watch2 = false) {
  435. var _a, _b, _c;
  436. if (!ID2) {
  437. return;
  438. }
  439. if (cache[ID2] == void 0 || cache[ID2] != STATUS["AC"]) {
  440. const response = await getProblemAcInfo(ID2);
  441. if (isDev()) {
  442. console.log("query result response:", response);
  443. }
  444. if ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.question) {
  445. const status = (_c = (_b = response == null ? void 0 : response.data) == null ? void 0 : _b.question) == null ? void 0 : _c.status;
  446. if (cache[ID2] == void 0 || cache[ID2] != status) {
  447. cache[ID2] = status == null ? "null" : status;
  448. if (watch2) {
  449. if (isDev()) {
  450. console.log("save local status :", cache[ID2], "status = ", status, "get local status :", Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"])[ID2]);
  451. }
  452. watchSaveStatus(ID2, cache[ID2]);
  453. }
  454. createStatus(cache[ID2], cur);
  455. }
  456. } else {
  457. console.warn("query result is undefined");
  458. createStatus(cache[ID2], cur);
  459. }
  460. }
  461. }
  462. async function addProcess(reload = true, doms = void 0, asyncAc = false) {
  463. var _a;
  464. let problems_doms = Array.isArray(doms) ? doms : loadProblems();
  465. const cache = getLocalProblemStatus();
  466. let uid = 0, query_cnt = 0;
  467. const isReplaceEnglish = isEnglish();
  468. for (let i = 0; i < problems_doms.length; i++) {
  469. let cur = problems_doms[i].parentElement;
  470. if (!(cur instanceof HTMLElement)) {
  471. continue;
  472. }
  473. const ID2 = getId((_a = problems_doms[i]) == null ? void 0 : _a.href);
  474. if (!ID2) {
  475. continue;
  476. }
  477. if (install_pos()) {
  478. cur.style.listStyleType = "none";
  479. }
  480. if (isReplaceEnglish && problems_doms[i].href) {
  481. problems_doms[i].href = problems_doms[i].href.replace("leetcode.cn", "leetcode.com");
  482. }
  483. if (!cache[ID2] || cache[ID2] != STATUS["AC"] && asyncAc) {
  484. await sleep(50);
  485. await queryStatus(ID2, cache, cur, false);
  486. query_cnt++;
  487. if (query_cnt % 10 == 0) {
  488. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], cache);
  489. }
  490. } else {
  491. let status = cache[ID2];
  492. uid++;
  493. createStatus(status, cur);
  494. }
  495. }
  496. if (isDev()) {
  497. console.log("cache num :", uid, ",tot:", A.length);
  498. }
  499. getProcess();
  500. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], cache);
  501. let other = Array.from(document.querySelectorAll(`${linkCssSelector_pre()} p>a`)).filter((item) => item && item instanceof HTMLAnchorElement && isBilibili(item.href));
  502. for (let i = 0; i < other.length; i++) {
  503. createStatus("null", other[i]);
  504. }
  505. }
  506. const submitProblems = (url = window.location.href, timeout = 500) => {
  507. const ID2 = getId(url);
  508. if (!ID2) {
  509. return;
  510. }
  511. setTimeout(() => {
  512. const cache = getLocalProblemStatus();
  513. if (isDev()) {
  514. console.log("ID:", ID2, "query status: ", cache[ID2]);
  515. }
  516. queryStatus(ID2, cache, void 0, true);
  517. }, timeout);
  518. };
  519. const watchSaveStatus = (ID2, status) => {
  520. const cache = getLocalProblemStatus();
  521. if (cache[ID2] != "ac") {
  522. cache[ID2] = status;
  523. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], cache);
  524. window.localStorage.setItem(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_status_update__"], JSON.stringify({
  525. "id": ID2,
  526. "status": status
  527. }));
  528. }
  529. };
  530. const watchLinkStatusUpdate = (e) => {
  531. var _a;
  532. if (e.key != __0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_status_update__"]) {
  533. return;
  534. }
  535. let { id, status } = JSON.parse(e.newValue);
  536. if (!id || !status) {
  537. return;
  538. }
  539. let thisLink = `${CUR_URL}/problems/${id}`;
  540. if (isDev()) {
  541. console.log("update", thisLink, "status", status);
  542. }
  543. let link = document.querySelector(`${linkCssSelector}[href^="${CUR_URL}/problems/${id}"]`);
  544. if (!link || !(link == null ? void 0 : link.parentElement)) {
  545. let doms = loadProblems();
  546. for (let i = 0; i < doms.length; i++) {
  547. if (!doms[i] || !((_a = doms[i]) == null ? void 0 : _a.parentElement)) {
  548. continue;
  549. }
  550. if (doms[i].href.indexOf(thisLink) != -1) {
  551. link = doms[i];
  552. break;
  553. }
  554. }
  555. }
  556. createStatus(status, link);
  557. };
  558. function getAcCountKey(k) {
  559. if (!k) return "";
  560. return `0x3f_ac_key_${k}`;
  561. }
  562. function deleteAllACCountKeys() {
  563. let urls = initUrls();
  564. let keys = [];
  565. for (let urlInfo of urls) {
  566. let key = getAcCountKey(urlInfo.link);
  567. Cache$2.remove(key);
  568. keys.push(key);
  569. }
  570. Cache$2.remove(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"]);
  571. return keys;
  572. }
  573. async function getProcess() {
  574. var _a;
  575. loadProblems();
  576. const cache = getLocalProblemStatus();
  577. const config = initObj();
  578. const response = await githubProblem(true);
  579. const mapInfo = response[1];
  580. let cnt = 0;
  581. let tot = 0;
  582. for (let i = 0; i < A.length; i++) {
  583. let ID2 = getId(A[i].href);
  584. if (!(config == null ? void 0 : config.visiableMember) && ((_a = mapInfo.get(ID2)) == null ? void 0 : _a.member)) {
  585. continue;
  586. }
  587. if (ID2 && cache[ID2] == STATUS["AC"]) {
  588. cnt++;
  589. }
  590. tot++;
  591. }
  592. let url = window.location.href;
  593. if (A.length > 0 && getAcCountKey(url)) {
  594. Cache$2.set(getAcCountKey(url), { "tot": tot, "ac": cnt });
  595. }
  596. return [cnt, tot];
  597. }
  598. function getLocalProblemStatus() {
  599. return Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], true, Object.name);
  600. }
  601. function getRandomInfo(array) {
  602. if (!Array.isArray(array)) return void 0;
  603. return array[Math.floor(Math.random() * array.length)];
  604. }
  605. function isEnglish() {
  606. return Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type__"], Boolean.name) == true;
  607. }
  608. function changeEnglishType() {
  609. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type__"], !isEnglish());
  610. if (Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type_tips__"], String.name) != "NO") {
  611. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type_tips__"], "OK");
  612. }
  613. window.location.reload();
  614. }
  615. function installEnglishLinkChangeCommand() {
  616. if (!isLeetCodeCircleUrl() || isEnglishENV()) {
  617. return;
  618. }
  619. _GM_registerMenuCommand(`题目链接切换到${isEnglish() ? "国服🎈" : "美服🌎"}`, () => {
  620. changeEnglishType();
  621. }, { title: "将题单链接替换为国服或者替换为美服" });
  622. }
  623. async function githubProblem(not_filter_member = true) {
  624. let allProbmems;
  625. if (!Array.isArray(allProbmems) || allProbmems.length == 0) {
  626. let response = await getProblemsJSON();
  627. if (Array.isArray(response)) {
  628. allProbmems = [...response];
  629. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_all_problems__"], [...response]);
  630. }
  631. } else {
  632. allProbmems = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_all_problems__"], true, Array.name);
  633. }
  634. if (!Array.isArray(allProbmems)) {
  635. ElementPlus.ElMessage({
  636. type: "error",
  637. message: "随机题目失败获取不到任何信息 !请如果出现这种情况,请前往 https://github.com/wuxin0011/tampermonkey-script/issues 反馈",
  638. duration: 6e3
  639. });
  640. return;
  641. }
  642. let config = initObj();
  643. let urlsData = initUrls();
  644. let set = /* @__PURE__ */ new Set();
  645. for (let info of urlsData) {
  646. if (info.link && info.select) {
  647. set.add(info.link);
  648. }
  649. }
  650. let acMap = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], true, Object.name);
  651. if (isDev()) {
  652. console.log("config and set", config, set);
  653. console.log("acMap", acMap);
  654. }
  655. let infos = [];
  656. let mapInfo = /* @__PURE__ */ new Map();
  657. let totInfo = [];
  658. for (let info of allProbmems) {
  659. if (!(info == null ? void 0 : info.problemUrl) || !set.has(info == null ? void 0 : info.problemUrl) || !Array.isArray(info.problems) || info.problems.length == 0) {
  660. continue;
  661. }
  662. let cur_infos = [];
  663. for (let i = 0; Array.isArray(info.problems) && i < info.problems.length; i++) {
  664. try {
  665. let { title, url, member, score, titleSlug } = info.problems[i];
  666. if (!url || !title) continue;
  667. if (!(config == null ? void 0 : config.visiableMember) && member || !not_filter_member && member) {
  668. continue;
  669. }
  670. let new_obj = { title, url, member, score, titleSlug, "status": acMap[titleSlug] };
  671. infos.push(new_obj);
  672. cur_infos.push(new_obj);
  673. mapInfo.set(titleSlug, new_obj);
  674. } catch (e) {
  675. console.log("error", e);
  676. }
  677. }
  678. info.problems = cur_infos;
  679. totInfo.push(info);
  680. }
  681. return [infos, mapInfo, totInfo];
  682. }
  683. async function randomProblem() {
  684. let responseDatas = await githubProblem();
  685. let acMap = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], true, Object.name);
  686. let config = initObj();
  687. let problems = responseDatas[0];
  688. let infos = [];
  689. for (let i = 0; Array.isArray(problems) && i < problems.length; i++) {
  690. try {
  691. let { title, url, member, score, titleSlug } = problems[i];
  692. if (!url || !title) continue;
  693. if (isDev()) {
  694. }
  695. if (!(config == null ? void 0 : config.showAcConfig) && acMap[titleSlug] == "ac") {
  696. continue;
  697. }
  698. if (!(config == null ? void 0 : config.visiableMember) && member) {
  699. continue;
  700. }
  701. if (score != 0 && (score < (config == null ? void 0 : config.min) || score > (config == null ? void 0 : config.max))) {
  702. continue;
  703. }
  704. infos.push({ title, url, member, score, titleSlug, "status": acMap[titleSlug] });
  705. } catch (e) {
  706. console.log("error", e);
  707. }
  708. }
  709. let data = getRandomInfo(infos);
  710. if (data.url && isEnglish()) {
  711. data.url = data.url.replace(ZH_URL, EN_URL);
  712. }
  713. ElementPlus.ElMessage({
  714. dangerouslyUseHTMLString: !!(data && (data == null ? void 0 : data.url) && (data == null ? void 0 : data.title)),
  715. type: (data == null ? void 0 : data.url) && (data == null ? void 0 : data.title) ? "success" : "error",
  716. message: (data == null ? void 0 : data.url) && (data == null ? void 0 : data.title) ? `<div>随机题目☕:&nbsp;<a href="${data.url}" target="_blank" style="color:#5d99f2;">${data.title}</a> ${(data == null ? void 0 : data.score) && (data == null ? void 0 : data.score) > 0 ? `&nbsp;分值${data.score}` : ""}</div>` : `没有符合条件的题目,请重新配置条件!`,
  717. duration: 6e3
  718. });
  719. }
  720. function isEnglishENV() {
  721. return window.location.href.indexOf("https://leetcode.com") != -1;
  722. }
  723. const isHttp = (url) => /^https?:\/\/.*$/.test(url);
  724. const isLeetCodeCircleUrl = (url = window.location.href) => /^https?:\/\/leetcode\.(com|cn).*\/discuss\/.*/i.test(url);
  725. const isProblem = (url = window.location.href) => /^https?:\/\/leetcode\.(com|cn)\/problems\/.*/i.test(url);
  726. const isContest = (url = window.location.href) => /^https?:\/\/leetcode\.(com|cn)\/contest\/.*\/problems\/.*/.test(url);
  727. const isBilibili = (url = window.location.href) => /.*bilibili.*/.test(url);
  728. const isZH = (url = window.location.href) => /^https?:\/\/leetcode\.cn/.test(url);
  729. const sleep = async (time = 500) => new Promise((resolove) => setTimeout(resolove, time));
  730. const EN_URL = "https://leetcode.com";
  731. const ZH_URL = "https://leetcode.cn";
  732. const LC_COPY_HTML_PLUGIN = "https://greatest.deepsurf.us//zh-CN/scripts/491969-lc-to-markdown-txt-html";
  733. const EN_SOLUTION_DEMO = "https://leetcode.com/discuss/interview-question/6032972/leetcode";
  734. const CUR_URL = isEnglishENV() ? EN_URL : ZH_URL;
  735. const isDev = () => JSON.parse("false");
  736. async function GetHubJSONInfo(url) {
  737. return fetch(url, {
  738. method: "get",
  739. mode: "cors"
  740. }).then((res) => res.json());
  741. }
  742. async function getProblemsJSON() {
  743. return GetHubJSONInfo("https://raw.githubusercontent.com/wuxin0011/tampermonkey-script/main/0x3f-leetcode/0x3f.json");
  744. }
  745. const LEETCODE_PROBLEM_API = `${CUR_URL}/graphql/`;
  746. async function PostLeetCodeApi(data) {
  747. return fetch(LEETCODE_PROBLEM_API, {
  748. method: "POST",
  749. credentials: "include",
  750. headers: {
  751. "Content-Type": "application/json"
  752. },
  753. body: JSON.stringify(data)
  754. }).then((res) => res.json());
  755. }
  756. async function getProblemAcInfo(titleSlug) {
  757. return PostLeetCodeApi(postData(titleSlug));
  758. }
  759. const _export_sfc = (sfc, props) => {
  760. const target = sfc.__vccOpts || sfc;
  761. for (const [key, val] of props) {
  762. target[key] = val;
  763. }
  764. return target;
  765. };
  766. const _sfc_main$1 = {};
  767. const _withScopeId = (n) => (vue.pushScopeId("data-v-6b5a9c54"), n = n(), vue.popScopeId(), n);
  768. const _hoisted_1$1 = /* @__PURE__ */ vue.createStaticVNode('<h2 data-v-6b5a9c54> 🎈必读内容 </h2><ul data-v-6b5a9c54><li style="color:red !important;" data-v-6b5a9c54> 同步功能使用前请确保为登录状态 </li></ul><h2 data-v-6b5a9c54> ❓ 题单进度不一致 </h2><ul data-v-6b5a9c54><li data-v-6b5a9c54> 防止一次性访问题单太多,对服务器产生压力,所以采用单个题单访问然后保存状态 , 这样避免访问量问题 </li><li data-v-6b5a9c54> 默认情况下会缓存访问的题单情况,对于没有访问的题单,可以手动在对应题单中同步 </li><li data-v-6b5a9c54> 题目状态根据用户提交题目情况会实时更新,只会在提交访问一次 </li></ul><h2 data-v-6b5a9c54> ❓ 如何使用随机题目? </h2><ul data-v-6b5a9c54><li data-v-6b5a9c54> 这个可以根据自己要求,配置好之后,可以使用 <em data-v-6b5a9c54> ctrl + alt + j </em> 触发 </li><li data-v-6b5a9c54> 如果这个快捷键影响,可以在命令设置中关闭 </li></ul><h2 data-v-6b5a9c54> ❓ 如何使用美服 </h2>', 7);
  769. const _hoisted_8 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("h2", null, " 🔗 反馈更新 ", -1));
  770. function _sfc_render(_ctx, _cache) {
  771. const _component_el_link = vue.resolveComponent("el-link");
  772. return vue.openBlock(), vue.createElementBlock("div", null, [
  773. _hoisted_1$1,
  774. vue.createElementVNode("ul", null, [
  775. vue.createElementVNode("li", null, [
  776. vue.createTextVNode(" 处于网络安全策略,对于不同网站请求有 "),
  777. vue.createVNode(_component_el_link, {
  778. underline: false,
  779. href: "https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS",
  780. type: "primary",
  781. target: "_blank"
  782. }, {
  783. default: vue.withCtx(() => [
  784. vue.createTextVNode("跨域机制保护")
  785. ]),
  786. _: 1
  787. }),
  788. vue.createTextVNode(" 美服和国服是两个不同网站,因此无法实现不同网站题单同步 。 ")
  789. ]),
  790. vue.createElementVNode("li", null, [
  791. vue.createTextVNode(" 如果想使用美服,请复制一份题单到美服中 "),
  792. vue.createVNode(_component_el_link, {
  793. underline: false,
  794. href: "https://greatest.deepsurf.us//zh-CN/scripts/491969-lc-to-markdown-txt-html",
  795. type: "primary",
  796. target: "_blank"
  797. }, {
  798. default: vue.withCtx(() => [
  799. vue.createTextVNode("lc-to-markdown-txt-html")
  800. ]),
  801. _: 1
  802. }),
  803. vue.createTextVNode(" 这个插件来复制题单 ")
  804. ]),
  805. vue.createElementVNode("li", null, [
  806. vue.createVNode(_component_el_link, {
  807. underline: false,
  808. href: "https://leetcode.com/discuss/interview-question/6032972/leetcode",
  809. type: "primary",
  810. target: "_blank"
  811. }, {
  812. default: vue.withCtx(() => [
  813. vue.createTextVNode("美服题单演示")
  814. ]),
  815. _: 1
  816. })
  817. ])
  818. ]),
  819. _hoisted_8,
  820. vue.createElementVNode("ul", null, [
  821. vue.createElementVNode("li", null, [
  822. vue.createTextVNode(" 你可以在 "),
  823. vue.createVNode(_component_el_link, {
  824. underline: false,
  825. href: "https://greatest.deepsurf.us//zh-CN/scripts/501134-0x3f-problem-solution/feedback",
  826. type: "success",
  827. target: "_blank"
  828. }, {
  829. default: vue.withCtx(() => [
  830. vue.createTextVNode("油猴")
  831. ]),
  832. _: 1
  833. }),
  834. vue.createTextVNode("   "),
  835. vue.createVNode(_component_el_link, {
  836. underline: false,
  837. href: "https://scriptcat.org/zh-CN/script-show-page/1967",
  838. type: "success",
  839. target: "_blank"
  840. }, {
  841. default: vue.withCtx(() => [
  842. vue.createTextVNode("脚本猫")
  843. ]),
  844. _: 1
  845. }),
  846. vue.createTextVNode(" 中更新或下载 ")
  847. ]),
  848. vue.createElementVNode("li", null, [
  849. vue.createVNode(_component_el_link, {
  850. underline: false,
  851. href: "https://greatest.deepsurf.us//zh-CN/scripts/501134-0x3f-problem-solution/feedback",
  852. type: "primary",
  853. target: "_blank"
  854. }, {
  855. default: vue.withCtx(() => [
  856. vue.createTextVNode("点击")
  857. ]),
  858. _: 1
  859. }),
  860. vue.createTextVNode("这里反馈 或者 "),
  861. vue.createVNode(_component_el_link, {
  862. target: "_blank",
  863. underline: false,
  864. href: "https://github.com/wuxin0011/tampermonkey-script/issues",
  865. type: "primary"
  866. }, {
  867. default: vue.withCtx(() => [
  868. vue.createTextVNode("issues")
  869. ]),
  870. _: 1
  871. })
  872. ])
  873. ])
  874. ]);
  875. }
  876. const Q1 = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__scopeId", "data-v-6b5a9c54"]]);
  877. function Message(title = "确认操作", callback = () => {
  878. }, canlcelCallback = () => {
  879. }) {
  880. ElementPlus.ElMessageBox.confirm(
  881. `${title} ?`,
  882. "警告",
  883. {
  884. confirmButtonText: "确认",
  885. cancelButtonText: "取消",
  886. type: "warning"
  887. }
  888. ).then(() => {
  889. callback();
  890. }).catch(() => {
  891. ElementPlus.ElMessage({
  892. type: "info",
  893. message: "已取消"
  894. });
  895. canlcelCallback();
  896. });
  897. }
  898. function tips_message() {
  899. if (isEnglish() && isZH() && Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type_tips__"]) == "OK") {
  900. ElementPlus.ElMessageBox.alert(
  901. `<div>
  902. <p>检查到当前环境为国服,如果需要同步功能需要切换到美服,或者复制一份题单到美服自己使用 否则仅保留替换链接功能,没有同步功能 </p>
  903. <ul>
  904. <li>你可以使用<a style="color:blue;" target="_blank" href="${LC_COPY_HTML_PLUGIN}">lc-to-markdown-txt-html</a> 来复制题单 </li>
  905. <li><a style="color:red;" target="_blank" href="${EN_SOLUTION_DEMO}">查看美服题单示例</a> </li>
  906. <ul>
  907. <div>`,
  908. "提示",
  909. {
  910. dangerouslyUseHTMLString: true,
  911. showCancelButton: true,
  912. cancelButtonText: "下次再说",
  913. confirmButtonText: "不再提示"
  914. }
  915. ).then((e) => {
  916. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type_tips__"], "NO");
  917. }).catch((e) => {
  918. if (e == "cancel") {
  919. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_support_type_tips__"]) == "OK_1";
  920. ElementPlus.ElMessage.warning({
  921. message: "下次切换到美服环境提示"
  922. });
  923. }
  924. });
  925. }
  926. }
  927. function update_version() {
  928. GM_registerMenuCommand(`更新脚本🔗`, () => {
  929. ElementPlus.ElMessageBox.alert(
  930. `<div>
  931. <p>📣 提示:最近油猴需要科学工具才能访问,如果你使用油猴,可以到脚本猫中找到源代码,复制覆盖当前脚本也能更新 </p>
  932. <br/>
  933. <p><a style="color:blue;" target="_blank" href="https://scriptcat.org/zh-CN/script-show-page/1967/"> 脚本猫🐱 </a></p>
  934. <p><a style="color:blue;" target="_blank" href="https://greatest.deepsurf.us//zh-CN/scripts/501134-0x3f-problem-solution"> 油猴🐒 </a>【需要科学工具访问】</p>
  935. <p><a style="color:blue;" target="_blank" href="https://gfork.dahi.icu/zh-CN/scripts/501134-0x3f-problem-solution"> 油猴镜像🐒 </a> 【不保证镜像存在】</p>
  936. <p><a style="color:blue;" target="_blank" href="https://github.com/wuxin0011/tampermonkey-script/blob/main/0x3f-leetcode/dist/0x3f-leetcode-problems.js"> github 源代码更新 </a> 【最直接方式】</p>
  937. <div>`,
  938. "更新☕",
  939. {
  940. dangerouslyUseHTMLString: true,
  941. showCancelButton: true,
  942. cancelButtonText: "取消",
  943. confirmButtonText: "确认"
  944. }
  945. );
  946. }, { title: "点击更新更新脚本" });
  947. }
  948. function stop_disscuss_command() {
  949. if (isZH() && isLeetCodeCircleUrl()) {
  950. const is_stop = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_stop_discuss_"], false, Boolean.name);
  951. if (is_stop) {
  952. _GM_addStyle(".t6Fde{ display:none !important;}");
  953. }
  954. GM_registerMenuCommand(`${is_stop ? "开启" : "关闭"}右侧讨论区📣`, () => {
  955. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problme_stop_discuss_"], !is_stop);
  956. window.location.reload();
  957. }, { title: "如果认为右侧讨论区太难看可以直接屏蔽😅" });
  958. }
  959. }
  960. const _hoisted_1 = { class: "dialog-footer" };
  961. const _hoisted_2 = { class: "processs-flex" };
  962. const _hoisted_3 = { style: { "text-align": "center", "color": "#121212" } };
  963. const TARGET_URL = "https://leetcode.cn/u/endlesscheng/";
  964. const formLabelWidth = "44px";
  965. const _sfc_main = {
  966. __name: "App",
  967. setup(__props) {
  968. const fromData = vue.reactive(initObj());
  969. const tableButtonSize = vue.ref("default");
  970. let tableData = vue.reactive(initUrls());
  971. const keywords = vue.ref("");
  972. const dialogTableVisible = vue.ref(false);
  973. const showAddLocalButton = vue.computed(() => isLeetCodeCircleUrl());
  974. let urlsData = vue.computed(() => {
  975. let map = /* @__PURE__ */ new Map();
  976. let infos = tableData.filter((info2) => {
  977. if ((info2 == null ? void 0 : info2.title) && (info2 == null ? void 0 : info2.link) && !map.has(info2.link)) {
  978. map.set(info2.link, info2);
  979. return info2 && (info2.title && info2.title.indexOf(keywords.value) != -1 || info2.link && info2.link.indexOf(keywords.value) != -1);
  980. } else {
  981. return false;
  982. }
  983. });
  984. let tot = 0, ac = 0;
  985. for (let i = 0, c = info.length; i < infos.length; i++) {
  986. let info2 = infos[i];
  987. if (info2["ac"] && info2["tot"]) {
  988. tot += info2["tot"];
  989. ac += info2["ac"];
  990. }
  991. if (!info2["id"]) {
  992. info2["id"] = c + 1;
  993. c++;
  994. }
  995. }
  996. let type = isNaN(fromData.sortType) ? 0 : fromData.sortType;
  997. if (type == 0) {
  998. infos.sort((info1, info2) => info2.id - info1.id);
  999. } else if (type == 1) {
  1000. infos.sort((info1, info2) => info2.tot - info1.tot);
  1001. } else if (type == 2) {
  1002. infos.sort((info1, info2) => info2.ac - info1.ac);
  1003. } else if (type == 3) {
  1004. infos.sort((info1, info2) => computeProcess(info2.ac, info2.tot) - computeProcess(info1.ac, info1.tot));
  1005. }
  1006. infos.unshift({ "title": "灵茶题单完成情况", "link": TARGET_URL, "tot": tot, "ac": ac, "id": 67108863 });
  1007. return infos;
  1008. });
  1009. const rowIsDisabled = vue.computed(() => (info2) => asyncButtonLoad.value || info2 && info2.link == TARGET_URL);
  1010. const isDisabbled = vue.computed(() => !!tableData.find((v) => (v == null ? void 0 : v.link) && (v == null ? void 0 : v.link.indexOf(window.location.href)) != -1));
  1011. const dialogFormVisible = vue.ref(false);
  1012. const computeProcess = (ac = 0, tot = 0) => {
  1013. if (isNaN(ac) || isNaN(tot) || tot === 0) return 0;
  1014. let p = 0;
  1015. if (tot == ac) {
  1016. return 100;
  1017. }
  1018. const s = String(ac / tot);
  1019. try {
  1020. let x1 = s.split(".")[1] || "";
  1021. x1 = x1.padEnd(3, "0").substring(0, 3);
  1022. p = Math.min(100, Number(x1) / 10);
  1023. } catch (e) {
  1024. console.log("calc error", e.message, s == void 0, ac, tot);
  1025. p = (ac / tot).toFixed(3) * 100;
  1026. }
  1027. return isNaN(p) ? 0 : p;
  1028. };
  1029. const processColors = [
  1030. { color: "#f56c6c", percentage: 20 },
  1031. { color: "#1989fa", percentage: 40 },
  1032. { color: "#e6a23c", percentage: 60 },
  1033. { color: "#6f7ad3", percentage: 80 },
  1034. { color: "#67c23a", percentage: 100 }
  1035. ];
  1036. vue.watch(fromData, () => {
  1037. handlerProblem(vue.toRaw(Object.assign({}, fromData)));
  1038. });
  1039. const info = vue.reactive({
  1040. title: "",
  1041. link: "",
  1042. status: "add"
  1043. });
  1044. const addlocal = async () => {
  1045. if (!isDisabbled) {
  1046. return;
  1047. }
  1048. let [cur, tot] = await getProcess();
  1049. tableData.unshift({ title: document.title, link: window.location.href, "ac": cur, "tot": tot, "id": tableData.length + 10 });
  1050. };
  1051. const updateIndex = vue.ref(-1);
  1052. const handlerProblems = (status, updateInfo = { title: "", link: "", id: 0 }, index = -1) => {
  1053. dialogFormVisible.value = true;
  1054. info.status = status;
  1055. updateIndex.value = updateInfo.id;
  1056. Object.assign(info, updateInfo);
  1057. };
  1058. const handlerMessage = (u, title, link) => {
  1059. const a = u ? "添加" : "修改";
  1060. const error = !(!!title && isHttp(link));
  1061. if (error) {
  1062. ElementPlus.ElMessage.error(`${a} 失败 请保证标题或者链接有效 `);
  1063. } else {
  1064. ElementPlus.ElMessage.success(`${a} 成功 `);
  1065. }
  1066. return !error;
  1067. };
  1068. const addOrUpdate = () => {
  1069. if (!handlerMessage(info.status == "add", info.title, info.link)) {
  1070. return;
  1071. }
  1072. if (info.status == "add") {
  1073. tableData.unshift({ title: info.title, link: info.link, "ac": 0, "tot": 0, "id": tableData.length + 10 });
  1074. } else {
  1075. let id = updateIndex.value;
  1076. for (let i = 0; i < tableData.length; i++) {
  1077. if (tableData[i] && tableData[i].id && tableData[i]["id"] == id) {
  1078. tableData[i]["title"] = info.title;
  1079. tableData[i]["link"] = info.link;
  1080. break;
  1081. }
  1082. }
  1083. }
  1084. dialogFormVisible.value = false;
  1085. };
  1086. const deleteProblems = (id) => {
  1087. for (let i = 0; i < tableData.length; i++) {
  1088. if (tableData[i] && tableData[i].id && tableData[i]["id"] == id) {
  1089. delete tableData[i];
  1090. break;
  1091. }
  1092. }
  1093. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_urls__"], vue.toRaw(tableData));
  1094. };
  1095. const handlerDefault = () => {
  1096. Message("确认使用默认题单,将会重置题单", () => {
  1097. for (let i = 0; i < tableData.length; i++) {
  1098. delete tableData[i];
  1099. }
  1100. let infos = computeAcInfo(defaultUrls);
  1101. for (let item of infos) {
  1102. tableData.unshift(item);
  1103. }
  1104. ElementPlus.ElMessage({
  1105. type: "success",
  1106. message: "重置成功"
  1107. });
  1108. });
  1109. };
  1110. window.addEventListener("beforeunload", () => {
  1111. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_urls__"], vue.toRaw(tableData).filter((u) => u != null && u != void 0));
  1112. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_update__"], true);
  1113. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_add_cur__"], false);
  1114. });
  1115. vue.onMounted(async () => {
  1116. if (support_plugins()) {
  1117. let times = 30;
  1118. let loadTimeId = setInterval(() => {
  1119. let a = queryProblem();
  1120. times--;
  1121. if (Array.isArray(a) && a.length > 0) {
  1122. handlerProblem(vue.toRaw(Object.assign({}, fromData)));
  1123. addProcess();
  1124. window.clearInterval(loadTimeId);
  1125. }
  1126. if (times == 0) {
  1127. window.clearInterval(loadTimeId);
  1128. }
  1129. }, 200);
  1130. }
  1131. window.addEventListener("storage", (e) => {
  1132. watchLinkStatusUpdate(e);
  1133. });
  1134. });
  1135. _GM_registerMenuCommand(`题单配置信息🛠`, () => {
  1136. dialogTableVisible.value = !dialogTableVisible.value;
  1137. }, { title: "AC标记安装位置,默认左侧,刷新生效" });
  1138. const selectHandlerChange = (row) => {
  1139. let infos = [];
  1140. for (let i = 0; i < urlsData.value.length; i++) {
  1141. if (urlsData.value[i]["link"] == TARGET_URL) continue;
  1142. infos.push(vue.toRaw(Object.assign({}, urlsData.value[i])));
  1143. }
  1144. for (let i = 0; i < tableData.length; i++) {
  1145. if (row.id == tableData[i].id) {
  1146. tableData[i].select = row.select;
  1147. break;
  1148. }
  1149. }
  1150. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_urls__"], infos);
  1151. };
  1152. const asyncButtonLoad = vue.ref(false);
  1153. const asyncButtonLoadBreak = vue.ref(false);
  1154. const showProcess = vue.ref(false);
  1155. const allProblemNum = vue.ref(0);
  1156. const asyncProblemNum = vue.ref(0);
  1157. const asyncVisableDialog = vue.ref(false);
  1158. const showProblemsProcessInfo = vue.reactive({
  1159. title: "",
  1160. link: "",
  1161. cnt: "",
  1162. ac: "",
  1163. id: "",
  1164. select: true
  1165. });
  1166. const showProblemsInfo = (info2 = {}) => {
  1167. asyncVisableDialog.value = !asyncVisableDialog.value;
  1168. Object.assign(showProblemsProcessInfo, info2);
  1169. };
  1170. const loadProcess = vue.computed(() => computeProcess(asyncProblemNum.value, allProblemNum.value));
  1171. const asyncProblemStatus = async (row = {}) => {
  1172. if (!(row == null ? void 0 : row.link)) return;
  1173. let callback = async () => {
  1174. var _a, _b, _c, _d, _e;
  1175. let rowData = void 0;
  1176. let asyncAll = (row == null ? void 0 : row.link) == TARGET_URL;
  1177. let cache = Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], true, Object.name);
  1178. if (isDev()) {
  1179. console.log("async ac cache:", cache);
  1180. }
  1181. let map = /* @__PURE__ */ new Map();
  1182. try {
  1183. for (let info2 of tableData) {
  1184. if ((info2 == null ? void 0 : info2.link) && (info2 == null ? void 0 : info2.title) && (info2 == null ? void 0 : info2.id)) {
  1185. if (rowData == void 0 && (info2 == null ? void 0 : info2.id) == row.id) {
  1186. rowData = info2;
  1187. }
  1188. if (!map.has(info2.link)) {
  1189. map.set(info2.link, info2);
  1190. }
  1191. }
  1192. }
  1193. if (rowData) {
  1194. rowData.loading = true;
  1195. }
  1196. asyncButtonLoad.value = true;
  1197. asyncButtonLoadBreak.value = false;
  1198. allProblemNum.value = 0;
  1199. asyncProblemNum.value = 0;
  1200. showProcess.value = true;
  1201. await sleep(500);
  1202. let githubInfo = await githubProblem(fromData.visiableMember);
  1203. let jsonInfo = githubInfo[2];
  1204. let datas = [];
  1205. for (let i = 0; Array.isArray(jsonInfo) && i < jsonInfo.length; i++) {
  1206. let key = `${(_a = jsonInfo[i]) == null ? void 0 : _a.problemUrl}`;
  1207. let origin = map.get(key);
  1208. if (!origin) {
  1209. continue;
  1210. }
  1211. if (asyncAll) {
  1212. for (let p of jsonInfo[i].problems) {
  1213. datas.push(Object.assign({ "origin": jsonInfo[i].problemUrl }, p));
  1214. }
  1215. origin.tot = Math.max(jsonInfo[i].problems.length, 0);
  1216. origin.ac = 0;
  1217. } else if (jsonInfo[i].problemUrl == row.link) {
  1218. for (let p of jsonInfo[i].problems) {
  1219. datas.push(Object.assign({ "origin": jsonInfo[i].problemUrl }, p));
  1220. }
  1221. origin.tot = Math.max(jsonInfo[i].problems.length, 0);
  1222. origin.ac = 0;
  1223. break;
  1224. }
  1225. }
  1226. if (Array.isArray(datas) && datas.length > 0) {
  1227. allProblemNum.value = datas.length;
  1228. asyncProblemNum.value = 0;
  1229. let pre = 0;
  1230. for (let i = 0; i < datas.length; i++) {
  1231. let info2 = datas[i];
  1232. try {
  1233. if (asyncButtonLoadBreak.value) {
  1234. break;
  1235. }
  1236. await sleep(80);
  1237. let ID2 = info2.titleSlug;
  1238. let key = `${info2.origin}`;
  1239. let origin = map.get(key);
  1240. if (cache[ID2] != "ac") {
  1241. let response = await getProblemAcInfo(ID2);
  1242. const status = (_c = (_b = response == null ? void 0 : response.data) == null ? void 0 : _b.question) == null ? void 0 : _c.status;
  1243. cache[ID2] = status == null ? "null" : status;
  1244. }
  1245. if (origin) {
  1246. if (cache[ID2] == "ac") {
  1247. origin.ac = origin.ac + 1;
  1248. }
  1249. }
  1250. asyncProblemNum.value += 1;
  1251. if (loadProcess.value < pre && isDev()) {
  1252. console.warn("calc result is error");
  1253. }
  1254. pre = loadProcess.value;
  1255. } catch (e) {
  1256. if (isDev()) {
  1257. console.log("process error", e.message, "asyncProblemNum.value", asyncProblemNum.value, "all", allProblemNum.value);
  1258. }
  1259. }
  1260. if (i % 100 == 0) {
  1261. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], Object.assign({}, cache));
  1262. }
  1263. }
  1264. }
  1265. } catch (e) {
  1266. console.log("error", e);
  1267. } finally {
  1268. if (rowData) {
  1269. rowData.loading = false;
  1270. }
  1271. asyncButtonLoad.value = false;
  1272. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_urls__"], vue.toRaw(tableData));
  1273. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_ac_key__"], Object.assign({}, cache));
  1274. if (isDev()) {
  1275. console.log("同步完成🥰", asyncProblemNum.value, allProblemNum.value, loadProcess.value);
  1276. }
  1277. await sleep(500);
  1278. ElementPlus.ElMessage({
  1279. type: allProblemNum.value == asyncProblemNum.value ? "success" : asyncButtonLoadBreak.value ? "error" : "warning",
  1280. message: allProblemNum.value == asyncProblemNum.value ? `同步完成🥰` : asyncButtonLoadBreak.value ? `同步中断 ${loadProcess.value}% ` : `同步率 ${loadProcess.value}% `,
  1281. duration: 3e3
  1282. });
  1283. await sleep(6e3);
  1284. allProblemNum.value = 0;
  1285. asyncProblemNum.value = 0;
  1286. showProcess.value = false;
  1287. asyncButtonLoadBreak.value = false;
  1288. for (let i = 0; i < tableData.length; i++) {
  1289. if (getAcCountKey((_d = tableData[i]) == null ? void 0 : _d.link)) {
  1290. Cache$2.set(getAcCountKey(tableData[i].link), { "tot": tableData[i].tot, "ac": tableData[i].ac });
  1291. }
  1292. if ((_e = tableData[i]) == null ? void 0 : _e.loading) {
  1293. tableData[i].loading = false;
  1294. }
  1295. }
  1296. }
  1297. };
  1298. if (row.link == TARGET_URL) {
  1299. Message("该操作将同步所有题单,耗时可能较长 确认操作?", callback);
  1300. } else {
  1301. callback();
  1302. }
  1303. };
  1304. const q1 = vue.ref(false);
  1305. vue.ref(false);
  1306. return (_ctx, _cache) => {
  1307. const _component_el_dialog = vue.resolveComponent("el-dialog");
  1308. const _component_el_input = vue.resolveComponent("el-input");
  1309. const _component_el_form_item = vue.resolveComponent("el-form-item");
  1310. const _component_el_form = vue.resolveComponent("el-form");
  1311. const _component_el_button = vue.resolveComponent("el-button");
  1312. const _component_el_progress = vue.resolveComponent("el-progress");
  1313. const _component_el_col = vue.resolveComponent("el-col");
  1314. const _component_el_option = vue.resolveComponent("el-option");
  1315. const _component_el_select = vue.resolveComponent("el-select");
  1316. const _component_el_tooltip = vue.resolveComponent("el-tooltip");
  1317. const _component_el_row = vue.resolveComponent("el-row");
  1318. const _component_el_table_column = vue.resolveComponent("el-table-column");
  1319. const _component_el_link = vue.resolveComponent("el-link");
  1320. const _component_el_switch = vue.resolveComponent("el-switch");
  1321. const _component_el_table = vue.resolveComponent("el-table");
  1322. return vue.openBlock(), vue.createElementBlock("div", null, [
  1323. vue.createVNode(_component_el_dialog, {
  1324. modelValue: q1.value,
  1325. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => q1.value = $event)
  1326. }, {
  1327. default: vue.withCtx(() => [
  1328. vue.createVNode(Q1)
  1329. ]),
  1330. _: 1
  1331. }, 8, ["modelValue"]),
  1332. vue.createVNode(_component_el_dialog, {
  1333. modelValue: dialogFormVisible.value,
  1334. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => dialogFormVisible.value = $event),
  1335. title: `${info.status == "add" ? "添加" : "编辑"}`,
  1336. width: "400"
  1337. }, {
  1338. footer: vue.withCtx(() => [
  1339. vue.createElementVNode("div", _hoisted_1, [
  1340. vue.createVNode(_component_el_button, {
  1341. onClick: _cache[3] || (_cache[3] = ($event) => dialogFormVisible.value = false)
  1342. }, {
  1343. default: vue.withCtx(() => [
  1344. vue.createTextVNode("取消")
  1345. ]),
  1346. _: 1
  1347. }),
  1348. vue.createVNode(_component_el_button, { onClick: addOrUpdate }, {
  1349. default: vue.withCtx(() => [
  1350. vue.createTextVNode(" 确认 ")
  1351. ]),
  1352. _: 1
  1353. })
  1354. ])
  1355. ]),
  1356. default: vue.withCtx(() => [
  1357. vue.createVNode(_component_el_form, null, {
  1358. default: vue.withCtx(() => [
  1359. vue.createVNode(_component_el_form_item, {
  1360. label: "标题",
  1361. "label-width": formLabelWidth
  1362. }, {
  1363. default: vue.withCtx(() => [
  1364. vue.createVNode(_component_el_input, {
  1365. modelValue: info.title,
  1366. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => info.title = $event),
  1367. autocomplete: "off"
  1368. }, null, 8, ["modelValue"])
  1369. ]),
  1370. _: 1
  1371. }),
  1372. vue.createVNode(_component_el_form_item, {
  1373. label: "链接",
  1374. "label-width": formLabelWidth
  1375. }, {
  1376. default: vue.withCtx(() => [
  1377. vue.createVNode(_component_el_input, {
  1378. modelValue: info.link,
  1379. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => info.link = $event),
  1380. autocomplete: "off"
  1381. }, null, 8, ["modelValue"])
  1382. ]),
  1383. _: 1
  1384. })
  1385. ]),
  1386. _: 1
  1387. })
  1388. ]),
  1389. _: 1
  1390. }, 8, ["modelValue", "title"]),
  1391. vue.createVNode(_component_el_dialog, {
  1392. modelValue: dialogTableVisible.value,
  1393. "onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => dialogTableVisible.value = $event),
  1394. title: asyncButtonLoadBreak.value ? `同步已中断 ${asyncProblemNum.value}/${allProblemNum.value}` : showProcess.value ? loadProcess.value < 100 ? `同步中...${asyncProblemNum.value}/${allProblemNum.value}` : "统计完成" : "题单信息",
  1395. width: "60%"
  1396. }, {
  1397. default: vue.withCtx(() => [
  1398. showProcess.value ? (vue.openBlock(), vue.createBlock(_component_el_progress, {
  1399. key: 0,
  1400. color: processColors,
  1401. percentage: loadProcess.value,
  1402. "stroke-width": 15,
  1403. striped: "",
  1404. "striped-flow": "",
  1405. style: { "margin-bottom": "20px" },
  1406. status: `${loadProcess.value == 100 ? "success" : ""}`
  1407. }, null, 8, ["percentage", "status"])) : vue.createCommentVNode("", true),
  1408. vue.createVNode(_component_el_row, { gutter: 10 }, {
  1409. default: vue.withCtx(() => [
  1410. vue.createVNode(_component_el_col, { span: 4 }, {
  1411. default: vue.withCtx(() => [
  1412. vue.createVNode(_component_el_input, {
  1413. modelValue: keywords.value,
  1414. "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => keywords.value = $event),
  1415. placeholder: "请输入关键词过滤",
  1416. clearable: ""
  1417. }, null, 8, ["modelValue"])
  1418. ]),
  1419. _: 1
  1420. }),
  1421. vue.createVNode(_component_el_col, { span: 20 }, {
  1422. default: vue.withCtx(() => [
  1423. showAddLocalButton.value ? (vue.openBlock(), vue.createBlock(_component_el_button, {
  1424. key: 0,
  1425. plain: "",
  1426. onClick: addlocal,
  1427. disabled: isDisabbled.value,
  1428. size: tableButtonSize.value
  1429. }, {
  1430. default: vue.withCtx(() => [
  1431. vue.createTextVNode(" 添加本页 ")
  1432. ]),
  1433. _: 1
  1434. }, 8, ["disabled", "size"])) : vue.createCommentVNode("", true),
  1435. showAddLocalButton.value ? (vue.openBlock(), vue.createBlock(_component_el_button, {
  1436. key: 1,
  1437. plain: "",
  1438. onClick: _cache[6] || (_cache[6] = ($event) => handlerProblems("add")),
  1439. size: tableButtonSize.value
  1440. }, {
  1441. default: vue.withCtx(() => [
  1442. vue.createTextVNode(" 自定义 ")
  1443. ]),
  1444. _: 1
  1445. }, 8, ["size"])) : vue.createCommentVNode("", true),
  1446. vue.createVNode(_component_el_select, {
  1447. modelValue: fromData.sortType,
  1448. "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => fromData.sortType = $event),
  1449. style: { "margin": "0 5px", "width": "100px" },
  1450. disabled: asyncButtonLoad.value
  1451. }, {
  1452. default: vue.withCtx(() => [
  1453. vue.createVNode(_component_el_option, {
  1454. label: "默认排序",
  1455. value: 0
  1456. }, {
  1457. default: vue.withCtx(() => [
  1458. vue.createTextVNode("默认排序")
  1459. ]),
  1460. _: 1
  1461. }),
  1462. vue.createVNode(_component_el_option, {
  1463. label: "题目数量",
  1464. value: 1
  1465. }, {
  1466. default: vue.withCtx(() => [
  1467. vue.createTextVNode("题目数量")
  1468. ]),
  1469. _: 1
  1470. }),
  1471. vue.createVNode(_component_el_option, {
  1472. label: "AC数量",
  1473. value: 2
  1474. }, {
  1475. default: vue.withCtx(() => [
  1476. vue.createTextVNode("AC数量")
  1477. ]),
  1478. _: 1
  1479. }),
  1480. vue.createVNode(_component_el_option, {
  1481. label: "完成度",
  1482. value: 3
  1483. }, {
  1484. default: vue.withCtx(() => [
  1485. vue.createTextVNode("完成度")
  1486. ]),
  1487. _: 1
  1488. })
  1489. ]),
  1490. _: 1
  1491. }, 8, ["modelValue", "disabled"]),
  1492. vue.createVNode(_component_el_tooltip, { content: "同步所有题单" }, {
  1493. default: vue.withCtx(() => [
  1494. vue.createVNode(_component_el_button, {
  1495. type: asyncButtonLoad.value ? "success" : "danger",
  1496. onClick: _cache[8] || (_cache[8] = ($event) => asyncProblemStatus({ "link": "https://leetcode.cn/u/endlesscheng/" })),
  1497. size: tableButtonSize.value,
  1498. loading: asyncButtonLoad.value
  1499. }, {
  1500. default: vue.withCtx(() => [
  1501. vue.createTextVNode(vue.toDisplayString(asyncButtonLoad.value ? "同步中" : "同步题单"), 1)
  1502. ]),
  1503. _: 1
  1504. }, 8, ["type", "size", "loading"])
  1505. ]),
  1506. _: 1
  1507. }),
  1508. asyncButtonLoad.value ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
  1509. key: 2,
  1510. content: "点击中断同步"
  1511. }, {
  1512. default: vue.withCtx(() => [
  1513. asyncButtonLoad.value ? (vue.openBlock(), vue.createBlock(_component_el_button, {
  1514. key: 0,
  1515. type: "warning",
  1516. text: "",
  1517. onClick: _cache[9] || (_cache[9] = ($event) => asyncButtonLoadBreak.value = !asyncButtonLoadBreak.value),
  1518. size: tableButtonSize.value
  1519. }, {
  1520. default: vue.withCtx(() => [
  1521. vue.createTextVNode(" 中断同步 ")
  1522. ]),
  1523. _: 1
  1524. }, 8, ["size"])) : vue.createCommentVNode("", true)
  1525. ]),
  1526. _: 1
  1527. })) : vue.createCommentVNode("", true),
  1528. vue.createVNode(_component_el_tooltip, { content: "随机一道灵茶题单中题目,快捷键 Ctrl + Alt + J 可以触发" }, {
  1529. default: vue.withCtx(() => [
  1530. vue.createVNode(_component_el_button, {
  1531. type: "primary",
  1532. text: "",
  1533. onClick: vue.unref(randomProblem),
  1534. size: tableButtonSize.value
  1535. }, {
  1536. default: vue.withCtx(() => [
  1537. vue.createTextVNode(" 随机题目 ")
  1538. ]),
  1539. _: 1
  1540. }, 8, ["onClick", "size"])
  1541. ]),
  1542. _: 1
  1543. })
  1544. ]),
  1545. _: 1
  1546. })
  1547. ]),
  1548. _: 1
  1549. }),
  1550. vue.createVNode(_component_el_table, {
  1551. data: vue.unref(urlsData),
  1552. height: "300",
  1553. style: { "width": "100%", "margin-top": "10px" }
  1554. }, {
  1555. default: vue.withCtx(() => [
  1556. vue.createVNode(_component_el_table_column, { type: "index" }),
  1557. vue.createVNode(_component_el_table_column, {
  1558. label: "标题",
  1559. width: "auto",
  1560. align: "center"
  1561. }, {
  1562. default: vue.withCtx((scope) => [
  1563. vue.createVNode(_component_el_link, {
  1564. href: scope.row.link,
  1565. target: "_blank",
  1566. type: "default"
  1567. }, {
  1568. default: vue.withCtx(() => [
  1569. vue.createTextVNode(vue.toDisplayString(scope.row.title), 1)
  1570. ]),
  1571. _: 2
  1572. }, 1032, ["href"])
  1573. ]),
  1574. _: 1
  1575. }),
  1576. vue.createVNode(_component_el_table_column, {
  1577. label: "随机",
  1578. width: "70",
  1579. align: "center"
  1580. }, {
  1581. default: vue.withCtx((scope) => [
  1582. vue.createVNode(_component_el_switch, {
  1583. modelValue: scope.row.select,
  1584. "onUpdate:modelValue": ($event) => scope.row.select = $event,
  1585. onChange: ($event) => selectHandlerChange(scope.row),
  1586. disabled: rowIsDisabled.value(scope.row),
  1587. size: "small"
  1588. }, null, 8, ["modelValue", "onUpdate:modelValue", "onChange", "disabled"])
  1589. ]),
  1590. _: 1
  1591. }),
  1592. vue.createVNode(_component_el_table_column, {
  1593. label: "AC",
  1594. width: "70",
  1595. align: "center"
  1596. }, {
  1597. default: vue.withCtx((scope) => [
  1598. vue.createVNode(_component_el_link, {
  1599. type: "success",
  1600. underline: false,
  1601. onClick: ($event) => showProblemsInfo(scope.row)
  1602. }, {
  1603. default: vue.withCtx(() => [
  1604. vue.createTextVNode(vue.toDisplayString(isNaN(scope.row.ac) ? 0 : scope.row.ac), 1)
  1605. ]),
  1606. _: 2
  1607. }, 1032, ["onClick"])
  1608. ]),
  1609. _: 1
  1610. }),
  1611. vue.createVNode(_component_el_table_column, {
  1612. label: "Total",
  1613. width: "70",
  1614. align: "center"
  1615. }, {
  1616. default: vue.withCtx((scope) => [
  1617. vue.createVNode(_component_el_link, {
  1618. type: "primary",
  1619. underline: false,
  1620. onClick: ($event) => showProblemsInfo(scope.row)
  1621. }, {
  1622. default: vue.withCtx(() => [
  1623. vue.createTextVNode(vue.toDisplayString(isNaN(scope.row.tot) ? 0 : scope.row.tot), 1)
  1624. ]),
  1625. _: 2
  1626. }, 1032, ["onClick"])
  1627. ]),
  1628. _: 1
  1629. }),
  1630. vue.createVNode(_component_el_table_column, {
  1631. label: "进度",
  1632. width: "70",
  1633. align: "center"
  1634. }, {
  1635. default: vue.withCtx((scope) => [
  1636. vue.createVNode(_component_el_link, {
  1637. onClick: ($event) => showProblemsInfo(scope.row),
  1638. type: "warning",
  1639. underline: false
  1640. }, {
  1641. default: vue.withCtx(() => {
  1642. var _a, _b, _c;
  1643. return [
  1644. vue.createTextVNode(vue.toDisplayString(((_a = scope == null ? void 0 : scope.row) == null ? void 0 : _a.tot) == 0 ? 0 : `${computeProcess((_b = scope == null ? void 0 : scope.row) == null ? void 0 : _b.ac, (_c = scope == null ? void 0 : scope.row) == null ? void 0 : _c.tot)}%`), 1)
  1645. ];
  1646. }),
  1647. _: 2
  1648. }, 1032, ["onClick"])
  1649. ]),
  1650. _: 1
  1651. }),
  1652. vue.createVNode(_component_el_table_column, {
  1653. label: "操作",
  1654. width: "200px",
  1655. align: "center"
  1656. }, {
  1657. default: vue.withCtx((scope) => [
  1658. vue.createVNode(_component_el_button, {
  1659. loading: scope.row.loading,
  1660. onClick: ($event) => asyncProblemStatus(scope.row),
  1661. size: "small",
  1662. type: "success",
  1663. disabled: rowIsDisabled.value(scope.row),
  1664. link: ""
  1665. }, {
  1666. default: vue.withCtx(() => [
  1667. vue.createTextVNode(vue.toDisplayString(scope.row.loading ? "" : "同步"), 1)
  1668. ]),
  1669. _: 2
  1670. }, 1032, ["loading", "onClick", "disabled"]),
  1671. vue.createVNode(_component_el_button, {
  1672. onClick: ($event) => handlerProblems("update", scope.row, scope.$index),
  1673. size: "small",
  1674. type: "primary",
  1675. disabled: rowIsDisabled.value(scope.row),
  1676. link: ""
  1677. }, {
  1678. default: vue.withCtx(() => [
  1679. vue.createTextVNode("编辑")
  1680. ]),
  1681. _: 2
  1682. }, 1032, ["onClick", "disabled"]),
  1683. vue.createVNode(_component_el_button, {
  1684. onClick: ($event) => deleteProblems(scope.row.id),
  1685. size: "small",
  1686. type: "danger",
  1687. link: "",
  1688. disabled: rowIsDisabled.value(scope.row)
  1689. }, {
  1690. default: vue.withCtx(() => [
  1691. vue.createTextVNode("删除")
  1692. ]),
  1693. _: 2
  1694. }, 1032, ["onClick", "disabled"])
  1695. ]),
  1696. _: 1
  1697. })
  1698. ]),
  1699. _: 1
  1700. }, 8, ["data"]),
  1701. vue.createVNode(_component_el_row, {
  1702. gutter: 10,
  1703. style: { "margin": "10px 0" }
  1704. }, {
  1705. default: vue.withCtx(() => [
  1706. vue.createVNode(_component_el_col, { span: 10 }, {
  1707. default: vue.withCtx(() => [
  1708. vue.createTextVNode(" 会员  "),
  1709. vue.createVNode(_component_el_tooltip, { content: "过滤会员题目,会员题不会出现在随机题目中和讨论区显示。另外会员题目将不参与进度统计,默认显示" }, {
  1710. default: vue.withCtx(() => [
  1711. vue.createVNode(_component_el_switch, {
  1712. modelValue: fromData.visiableMember,
  1713. "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => fromData.visiableMember = $event)
  1714. }, null, 8, ["modelValue"])
  1715. ]),
  1716. _: 1
  1717. }),
  1718. showAddLocalButton.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
  1719. vue.createTextVNode(" 隐藏AC  "),
  1720. vue.createVNode(_component_el_tooltip, { content: "是否在讨论区显示AC题目,默认显示 " }, {
  1721. default: vue.withCtx(() => [
  1722. vue.createVNode(_component_el_switch, {
  1723. modelValue: fromData.hiddenAc,
  1724. "onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => fromData.hiddenAc = $event)
  1725. }, null, 8, ["modelValue"])
  1726. ]),
  1727. _: 1
  1728. })
  1729. ], 64)) : vue.createCommentVNode("", true),
  1730. vue.createTextVNode(" 随机ac  "),
  1731. vue.createVNode(_component_el_tooltip, { content: "随机题目配置: 过滤AC的题目,AC题目出现在随机题目中,默认不过滤" }, {
  1732. default: vue.withCtx(() => [
  1733. vue.createVNode(_component_el_switch, {
  1734. modelValue: fromData.showAcConfig,
  1735. "onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => fromData.showAcConfig = $event)
  1736. }, null, 8, ["modelValue"])
  1737. ]),
  1738. _: 1
  1739. })
  1740. ]),
  1741. _: 1
  1742. }),
  1743. vue.createVNode(_component_el_col, { span: 8 }, {
  1744. default: vue.withCtx(() => [
  1745. vue.createTextVNode("   "),
  1746. vue.createVNode(_component_el_tooltip, { content: "随机题目和讨论区题目将会在这个区间(没有分数题目无法操作)" }, {
  1747. default: vue.withCtx(() => [
  1748. vue.createVNode(_component_el_link, {
  1749. underline: false,
  1750. type: "primary"
  1751. }, {
  1752. default: vue.withCtx(() => [
  1753. vue.createTextVNode("分数区间")
  1754. ]),
  1755. _: 1
  1756. })
  1757. ]),
  1758. _: 1
  1759. }),
  1760. vue.createTextVNode("   "),
  1761. vue.createVNode(_component_el_input, {
  1762. modelValue: fromData.min,
  1763. "onUpdate:modelValue": _cache[13] || (_cache[13] = ($event) => fromData.min = $event),
  1764. "aria-placeholder": "",
  1765. placeholder: " min ",
  1766. style: { "width": "60px" }
  1767. }, null, 8, ["modelValue"]),
  1768. vue.createTextVNode("- "),
  1769. vue.createVNode(_component_el_input, {
  1770. modelValue: fromData.max,
  1771. "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => fromData.max = $event),
  1772. "aria-placeholder": "",
  1773. placeholder: " max",
  1774. style: { "width": "60px" }
  1775. }, null, 8, ["modelValue"])
  1776. ]),
  1777. _: 1
  1778. }),
  1779. vue.createVNode(_component_el_col, { span: 6 }, {
  1780. default: vue.withCtx(() => [
  1781. vue.createVNode(_component_el_tooltip, { content: "重置题单" }, {
  1782. default: vue.withCtx(() => [
  1783. vue.createVNode(_component_el_button, {
  1784. plain: "",
  1785. onClick: handlerDefault,
  1786. size: tableButtonSize.value,
  1787. disabled: showProcess.value
  1788. }, {
  1789. default: vue.withCtx(() => [
  1790. vue.createTextVNode(" 默认 ")
  1791. ]),
  1792. _: 1
  1793. }, 8, ["size", "disabled"])
  1794. ]),
  1795. _: 1
  1796. }),
  1797. vue.createVNode(_component_el_button, {
  1798. plain: "",
  1799. onClick: _cache[15] || (_cache[15] = ($event) => q1.value = !q1.value),
  1800. size: tableButtonSize.value
  1801. }, {
  1802. default: vue.withCtx(() => [
  1803. vue.createTextVNode(" 使用说明 ")
  1804. ]),
  1805. _: 1
  1806. }, 8, ["size"])
  1807. ]),
  1808. _: 1
  1809. })
  1810. ]),
  1811. _: 1
  1812. })
  1813. ]),
  1814. _: 1
  1815. }, 8, ["modelValue", "title"]),
  1816. vue.createVNode(_component_el_dialog, {
  1817. modelValue: asyncVisableDialog.value,
  1818. "onUpdate:modelValue": _cache[17] || (_cache[17] = ($event) => asyncVisableDialog.value = $event),
  1819. width: "35%"
  1820. }, {
  1821. default: vue.withCtx(() => [
  1822. vue.createElementVNode("p", null, [
  1823. vue.createVNode(_component_el_link, {
  1824. href: showProblemsProcessInfo.link,
  1825. type: "info",
  1826. underline: false
  1827. }, {
  1828. default: vue.withCtx(() => [
  1829. vue.createTextVNode(vue.toDisplayString(showProblemsProcessInfo.title), 1)
  1830. ]),
  1831. _: 1
  1832. }, 8, ["href"])
  1833. ]),
  1834. vue.createElementVNode("div", _hoisted_2, [
  1835. vue.createVNode(_component_el_progress, {
  1836. type: "circle",
  1837. percentage: computeProcess(showProblemsProcessInfo.ac, showProblemsProcessInfo.tot),
  1838. color: processColors
  1839. }, {
  1840. default: vue.withCtx(({ percentage }) => [
  1841. vue.createElementVNode("p", null, vue.toDisplayString(percentage) + "%", 1)
  1842. ]),
  1843. _: 1
  1844. }, 8, ["percentage"])
  1845. ]),
  1846. vue.createElementVNode("p", _hoisted_3, vue.toDisplayString(showProblemsProcessInfo.ac) + " / " + vue.toDisplayString(showProblemsProcessInfo.tot), 1)
  1847. ]),
  1848. _: 1
  1849. }, 8, ["modelValue"])
  1850. ]);
  1851. };
  1852. }
  1853. };
  1854. const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-76dd1ba0"]]);
  1855. const cssLoader = (e) => {
  1856. const t = GM_getResourceText(e);
  1857. return GM_addStyle(t), t;
  1858. };
  1859. cssLoader("elementPlusCss");
  1860. const stopRankingKey = "__is_stop_rating_ranking__";
  1861. let conetstTimeId = null;
  1862. function run$1() {
  1863. const container = document.querySelector(".contest-question-info .list-group");
  1864. if (!container) return;
  1865. const ls = Array.from(container.querySelectorAll(".list-group-item .pull-right"));
  1866. for (let i = 0; i < 4; i++) {
  1867. if (i >= ls.length) {
  1868. break;
  1869. }
  1870. if (ls[i] instanceof HTMLElement) {
  1871. ls[i].textContent = "0";
  1872. }
  1873. }
  1874. window.clearInterval(conetstTimeId);
  1875. }
  1876. function startStopRanking() {
  1877. if (!isContest(window.location.href)) {
  1878. return;
  1879. }
  1880. const isNext = !!document.querySelector("#__next");
  1881. if (isNext) {
  1882. return;
  1883. }
  1884. const use = Cache$2.get(stopRankingKey);
  1885. if (use) {
  1886. conetstTimeId = setInterval(() => {
  1887. run$1();
  1888. }, 10);
  1889. }
  1890. _GM_registerMenuCommand(`${use ? "使用" : "关闭"} 排行榜`, () => {
  1891. Cache$2.set(stopRankingKey, !use);
  1892. window.location.reload();
  1893. }, { title: "对于不想看到排行榜的可以使用此功能 默认开启" });
  1894. }
  1895. const local_url$1 = window.location.href;
  1896. let loadID$1 = 0;
  1897. let submitCnt = 0;
  1898. let submitbutton = null;
  1899. function watchDom(dom) {
  1900. if (!(dom instanceof HTMLElement)) {
  1901. return;
  1902. }
  1903. let m = new MutationObserver(() => {
  1904. if (submitCnt % 2 == 1) {
  1905. submitProblems(local_url$1);
  1906. }
  1907. submitCnt++;
  1908. });
  1909. m.observe(dom, {
  1910. childList: true,
  1911. attributes: true
  1912. });
  1913. }
  1914. function handler() {
  1915. loadID$1++;
  1916. let findSubmitButton = function(sel) {
  1917. if (!sel) return null;
  1918. return Array.from(document.querySelectorAll(sel && { length: 0 })).find((e) => {
  1919. return e && e.innerText == "提交解答" || e.innerText == "提交";
  1920. });
  1921. };
  1922. const isNext = !!document.querySelector("#__next");
  1923. submitbutton = findSubmitButton(isProblem(local_url$1) || isNext ? "" : ".question-detail-bottom .pull-right button");
  1924. if (!submitbutton) {
  1925. submitbutton = document.querySelector('[data-e2e-locator="console-submit-button"]');
  1926. }
  1927. if (submitbutton) {
  1928. watchDom(submitbutton);
  1929. submitbutton.addEventListener("click", () => {
  1930. submitProblems(local_url$1, 10 * 1e3);
  1931. });
  1932. } else if (loadID$1 < 10) {
  1933. setTimeout(() => {
  1934. handlerNotFound();
  1935. }, 3e3);
  1936. }
  1937. }
  1938. function watchSubmit() {
  1939. if (!isProblem()) {
  1940. return;
  1941. }
  1942. try {
  1943. if ((window == null ? void 0 : window.fetch) && (window == null ? void 0 : window.unsafeWindow)) {
  1944. let originalFetch = window == null ? void 0 : window.fetch;
  1945. window.unsafeWindow.fetch = function() {
  1946. return originalFetch.apply(this, arguments).then(function(response) {
  1947. let res = response.clone();
  1948. res.text().then(function(bodyText) {
  1949. let url = res.url;
  1950. if (isDev()) {
  1951. console.log("query result", bodyText);
  1952. }
  1953. if (!/https:\/\/leetcode\.(cn|com)\/submissions\/detail\/\d+\/check\/.*/.test(url)) {
  1954. return;
  1955. }
  1956. if (res.status == 200 && res.ok) {
  1957. let result = JSON.parse(bodyText);
  1958. const ID2 = getId(local_url$1);
  1959. const status = (result == null ? void 0 : result.status_msg) == "Accepted" ? "ac" : (result == null ? void 0 : result.status_msg) == "Wrong Answer" ? "notac" : "null";
  1960. watchSaveStatus(ID2, status);
  1961. }
  1962. const cache = Cache.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_ac_key__"], true, Object.name);
  1963. if (cache[ID] == null || cache[Id] == void 0) {
  1964. submitProblems(local_url$1);
  1965. }
  1966. });
  1967. return response;
  1968. });
  1969. };
  1970. } else {
  1971. console.warn("浏览器当前环境不支持 unsafeWindow 将做兼容处理 ");
  1972. handler();
  1973. }
  1974. } catch (e) {
  1975. console.error(e);
  1976. }
  1977. }
  1978. const local_url = window.location.href;
  1979. const randomProblemKey = () => Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_random_problems_key__"]) == void 0 ? true : Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_random_problems_key__"]);
  1980. let Container = null;
  1981. Cache$2.get(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_button_is_none__"], true, Boolean.name);
  1982. if (isProblem() || isLeetCodeCircleUrl()) {
  1983. const start = () => {
  1984. Container = document.createElement("div");
  1985. const body = document.querySelector("body");
  1986. body.append(Container);
  1987. Container.style.display = "block";
  1988. return Container;
  1989. };
  1990. let dom = start();
  1991. const VueApp = vue.createApp(App);
  1992. VueApp.use(ElementPlus).mount(dom);
  1993. }
  1994. if (isProblem() || isLeetCodeCircleUrl()) {
  1995. _GM_registerMenuCommand(`随机一道题 ☕`, randomProblem, { title: "随机一道题目,你可以通过ctrl+atl+j显示一道题目" });
  1996. _GM_registerMenuCommand(`${randomProblemKey() ? "关闭" : "启用"} 随机题目快捷键 ☕`, () => {
  1997. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_random_problems_key__"], !randomProblemKey());
  1998. window.location.reload();
  1999. }, { title: "该功能是随机一道题的快捷键,你可以通过ctrl+atl+j显示一道题目" });
  2000. if (isLeetCodeCircleUrl()) {
  2001. installEnglishLinkChangeCommand();
  2002. }
  2003. if (randomProblemKey()) {
  2004. document.addEventListener("keydown", async function(event) {
  2005. if (event.ctrlKey && event.altKey && event.key === "j") {
  2006. randomProblem();
  2007. }
  2008. });
  2009. }
  2010. }
  2011. let loadID = 0;
  2012. async function run() {
  2013. loadID++;
  2014. if (isProblem(local_url)) {
  2015. await sleep(3e3);
  2016. if (isProblem(local_url) && loadID == 1) {
  2017. submitProblems(local_url);
  2018. }
  2019. } else if (isLeetCodeCircleUrl(local_url)) {
  2020. stop_disscuss_command();
  2021. _GM_registerMenuCommand(`安装到${install_pos() ? "右侧" : "左侧"} 🎁`, () => {
  2022. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_insert_pos__"], install_pos());
  2023. window.location.reload();
  2024. }, { title: "AC标记安装位置,默认左侧,刷新生效" });
  2025. _GM_registerMenuCommand(`清空题目状态缓存 🚀`, () => {
  2026. Message("确认清空题目状态缓存", () => {
  2027. deleteAllACCountKeys();
  2028. window.location.reload();
  2029. });
  2030. }, { title: "如果题目状态出现问题,可以试试,一般情况下不建议使用" });
  2031. _GM_registerMenuCommand(`同步题目状态 🚀`, () => {
  2032. Message("确认同步题目状态", async () => {
  2033. await addProcess(true, void 0, true);
  2034. });
  2035. }, { title: "如果不在同一个浏览器答题,会出现ac题目状态没有及时同步,可以使用此功能" });
  2036. _GM_registerMenuCommand(`${initObj().onlyUrls ? "仅在收藏题单页面生效" : "所有题单生效"}`, () => {
  2037. const u = initObj();
  2038. u.onlyUrls = !u.onlyUrls;
  2039. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_solution__"], u);
  2040. }, { title: "插件默认会在所有讨论发布页生效,如果只想在收藏链接生效,可以使用此功能" });
  2041. _GM_registerMenuCommand(`添加本页`, () => {
  2042. const urls = initUrls();
  2043. let ok = false;
  2044. let url = window.location.href;
  2045. for (let info of urls) {
  2046. if (!info || !(info == null ? void 0 : info.link)) {
  2047. continue;
  2048. }
  2049. if (info.link.indexOf(url) != -1) {
  2050. ok = true;
  2051. break;
  2052. }
  2053. }
  2054. if (ok) {
  2055. ElementPlus.ElMessage({
  2056. message: "收藏失败,链接已经存在!",
  2057. type: "error"
  2058. });
  2059. } else {
  2060. if (isLeetCodeCircleUrl(url) && url.indexOf("view") != -1) {
  2061. try {
  2062. url = url.split("view")[0];
  2063. } catch (e) {
  2064. url = window.location.href;
  2065. }
  2066. }
  2067. urls.unshift({
  2068. title: document.title,
  2069. link: url
  2070. });
  2071. Container.style.display = "block";
  2072. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_urls__"], urls);
  2073. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_update__"], true);
  2074. Cache$2.set(__0X3F_PROBLEM_KEYS__$1["__0x3f_problmes_add_cur__"], true);
  2075. ElementPlus.ElMessage({
  2076. message: "收藏成功!刷新生效",
  2077. type: "success"
  2078. });
  2079. }
  2080. });
  2081. }
  2082. }
  2083. tips_message();
  2084. update_version();
  2085. watchSubmit();
  2086. run();
  2087. startStopRanking();
  2088.  
  2089. })(ElementPlus, Vue);