Greasy Fork is available in English.

0x3f-problem-solution

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

2024-08-22 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

  1. // ==UserScript==
  2. // @name 0x3f-problem-solution
  3. // @namespace https://greatest.deepsurf.us/zh-CN/scripts/501134-0x3f-problem-solution
  4. // @version 0.0.4.4
  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://greatest.deepsurf.us/zh-CN/scripts/501134-0x3f-problem-solution
  10. // @match https://leetcode.cn/circle/discuss/*
  11. // @match https://leetcode.cn/problems/*
  12. // @match https://leetcode.cn/contest/weekly-contest-*/problems/*
  13. // @match https://leetcode.cn/contest/biweekly-contest-*/problems/*
  14. // @require https://cdn.jsdelivr.net/npm/vue@3.4.31/dist/vue.global.prod.js
  15. // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
  16. // @require https://unpkg.com/element-plus@2.7.6/dist/index.full.js
  17. // @resource elementPlusCss https://unpkg.com/element-plus@2.7.6/dist/index.css
  18. // @grant GM_addStyle
  19. // @grant GM_deleteValue
  20. // @grant GM_getResourceText
  21. // @grant GM_getValue
  22. // @grant GM_registerMenuCommand
  23. // @grant GM_setValue
  24. // ==/UserScript==
  25.  
  26. (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const e=document.createElement("style");e.textContent=t,document.head.append(e)})(" .m-setting-button[data-v-3dc7143a]{position:fixed;top:200px;right:0;z-index:100000}.m-button[data-v-3dc7143a]{margin-left:16px!important;padding:5px!important;font-size:14px!important}.processs-flex[data-v-3dc7143a]{display:flex;justify-content:center;align-items:center} ");
  27.  
  28. (function (vue, ElementPlus) {
  29. 'use strict';
  30.  
  31. var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
  32. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  33. var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  34. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  35. class Cache {
  36. set(k, v) {
  37. _GM_setValue(k, v);
  38. }
  39. get(k, parse = true, name = String.name) {
  40. try {
  41. let v = _GM_getValue(k);
  42. switch (name) {
  43. case String.name:
  44. if (v == null) {
  45. return "null";
  46. }
  47. return v;
  48. case Object.name:
  49. if (v == null || v == void 0 || typeof v != "object") {
  50. return {};
  51. }
  52. return v;
  53. case Boolean.name:
  54. if (v === null || v == void 0) {
  55. return false;
  56. }
  57. if (v == false || v == "false" || v == "" || v == "null") {
  58. return false;
  59. }
  60. return v;
  61. case Array.name:
  62. if (v === null || v == void 0 || !Array.isArray(v)) {
  63. return [];
  64. }
  65. return v;
  66. default:
  67. return v;
  68. }
  69. } catch (E) {
  70. return null;
  71. }
  72. }
  73. remove(k) {
  74. _GM_deleteValue(k);
  75. }
  76. }
  77. const Cache$1 = new Cache();
  78. const _export_sfc = (sfc, props) => {
  79. const target = sfc.__vccOpts || sfc;
  80. for (const [key, val] of props) {
  81. target[key] = val;
  82. }
  83. return target;
  84. };
  85. const _sfc_main$1 = {};
  86. const _hoisted_1$1 = /* @__PURE__ */ vue.createElementVNode("p", null, " 1. 本人目前测试过,没有封号,但是对于查询过题目会缓存在本地,因此尽量不要清空浏览器缓存 ", -1);
  87. const _hoisted_2$1 = /* @__PURE__ */ vue.createElementVNode("p", null, " 2. 脚本会监控题做题提交状态 ,当题目提交时候会缓存题目状态,如果题单中有这个题目,会直接从缓存中获取 ", -1);
  88. const _hoisted_3$1 = [
  89. _hoisted_1$1,
  90. _hoisted_2$1
  91. ];
  92. function _sfc_render(_ctx, _cache) {
  93. return vue.openBlock(), vue.createElementBlock("div", null, _hoisted_3$1);
  94. }
  95. const Q1 = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render]]);
  96. function Message(title = "确认操作", callback = () => {
  97. }, canlcelCallback = () => {
  98. }) {
  99. ElementPlus.ElMessageBox.confirm(
  100. `${title} ?`,
  101. "警告",
  102. {
  103. confirmButtonText: "确认",
  104. cancelButtonText: "取消",
  105. type: "warning"
  106. }
  107. ).then(() => {
  108. callback();
  109. }).catch(() => {
  110. ElementPlus.ElMessage({
  111. type: "info",
  112. message: "已取消"
  113. });
  114. canlcelCallback();
  115. });
  116. }
  117. const isLeetCodeCircleUrl = (url = window.location.href) => url && url.indexOf("https://leetcode.cn/circle") != -1;
  118. const isProblem = (url = window.location.href) => /^https?:\/\/leetcode.cn\/problems\/.*/i.test(url);
  119. const isContest = (url = window.location.href) => url.indexOf("https://leetcode.cn/contest/weekly-contest") != -1 || url.indexOf("https://leetcode.cn/contest/biweekly-contest") != -1;
  120. const width = 14;
  121. const height = 14;
  122. const problemFinsh = () => `
  123.  
  124. <svg width="${width}px" height="${height}px" status="ac" viewBox="0 0 1024 1024" version="1.1"
  125. xmlns="http://www.w3.org/2000/svg">
  126. <path d="M512 512m-448 0a448 448 0 1 0 896 0 448 448 0 1 0-896 0Z" fill="#4CAF50" />
  127. <path
  128. d="M738.133333 311.466667L448 601.6l-119.466667-119.466667-59.733333 59.733334 179.2 179.2 349.866667-349.866667z"
  129. fill="#CCFF90" />
  130. </svg>
  131.  
  132. `;
  133. const problemsTry = () => `
  134. <svg width="${width}px" height="${height}px" status="notac" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
  135. xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512"
  136. style="enable-background:new 0 0 512 512;" xml:space="preserve">
  137. <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
  138. S390.101,12.8,256,12.8z" />
  139. <g>
  140. <path style="fill:#573A32;" d="M256,115.2c-49.271,0-92.561,25.353-117.726,63.676l18.859,18.859
  141. 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
  142. C396.8,178.244,333.764,115.2,256,115.2z" />
  143. <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
  144. 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" />
  145. <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
  146. 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
  147. C334.822,348.194,298.266,371.2,256,371.2z" />
  148. </g>
  149. </svg>
  150.  
  151. `;
  152. const problemsNo = () => install_pos() ? `
  153. <svg width="${width}px" height="${height}px" status="null" 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>
  154. ` : ``;
  155. const createStatus = (status, link) => {
  156. let node;
  157. if (!link) {
  158. return;
  159. }
  160. node = link instanceof HTMLAnchorElement ? link.parentElement : link;
  161. if (node) {
  162. node.status = status;
  163. }
  164. let installSVG = "";
  165. if (status == STATUS["AC"]) {
  166. installSVG = problemFinsh();
  167. } else if (status == STATUS["notac"]) {
  168. installSVG = problemsTry();
  169. } else if (status == STATUS["NO"]) {
  170. installSVG = problemsNo();
  171. } else {
  172. installSVG = "";
  173. }
  174. let svg = node.querySelector("svg");
  175. if (svg) {
  176. if (svg.getAttribute("status") == status || svg.getAttribute("status") == STATUS["AC"]) {
  177. return false;
  178. }
  179. svg.remove();
  180. }
  181. node.innerHTML = install_pos() ? installSVG + node.innerHTML : node.innerHTML + installSVG;
  182. return true;
  183. };
  184. const inf = 4e3;
  185. const mi = 1e3;
  186. const __0X3F_PROBLEM_KEYS__ = {
  187. "__0x3f_problmes_solution__": "__0x3f_problmes_solution__",
  188. // 基本信息
  189. "__0x3f_problmes_urls__": "__0x3f_problmes_urls__",
  190. // 题单key
  191. "__0x3f_problmes_update__": "__0x3f_problmes_update__",
  192. // 是否修改了默认题单key
  193. "__0x3f_problmes_button_is_none__": "__is_none_0x3f_problmes_button__",
  194. // 是否隐藏设置按钮
  195. "__0x3f_problmes_insert_pos__": "__0x3f_problmes_insert_pos__",
  196. // 安装位置
  197. "__0x3f_problmes_status_update__": "__0x3f_problmes_status_update__",
  198. "__0x3f_problmes_plugin_load_ok__": "__0x3f_problmes_plugin_load_ok__",
  199. // 是否使用插件
  200. "__0x3f_problmes_add_cur__": "__0x3f_problmes_add_cur__",
  201. // 添加 url
  202. "__0x3f_problmes_ac_key__": "__local_ok_problem_key__",
  203. // ac key
  204. "__0x3f_problmes_ac_version__": "__0x3f_problmes_ac_version__"
  205. // TODO ac key version
  206. };
  207. const STATUS = {
  208. "AC": "ac",
  209. "NO": "null",
  210. "notac": "notac"
  211. };
  212. const defaultObj = {
  213. min: mi,
  214. max: inf,
  215. visiableMember: true,
  216. onlyUrls: false,
  217. useDefaultSetting: true,
  218. hiddenAc: false
  219. };
  220. function install_pos() {
  221. return !Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_insert_pos__"], false, Boolean.name);
  222. }
  223. function isShow(text, min, max) {
  224. if (!text) {
  225. return true;
  226. }
  227. let res = text.match(/\d+/ig);
  228. if (!res) {
  229. return true;
  230. }
  231. if (Array.isArray(res) && res.length < 2) {
  232. return true;
  233. }
  234. let s = 0;
  235. for (let i = res.length - 1; i >= 0; i--) {
  236. s = res[i];
  237. if (s >= mi && s <= inf) {
  238. return s >= min && s <= max;
  239. }
  240. }
  241. return true;
  242. }
  243. let A = void 0;
  244. const linkCssSelector = `#lc-content [class*="CollapsibleMarkdownContent"] [class*="MarkdownContent"] li>a`;
  245. const queryProblem = () => Array.from(document.querySelectorAll(linkCssSelector)).filter((item) => item && item instanceof HTMLAnchorElement && isProblem(item.href));
  246. function loadProblems() {
  247. A = queryProblem();
  248. return A;
  249. }
  250. function handlerProblem(data) {
  251. var _a;
  252. try {
  253. loadProblems();
  254. let { min, max, visiableMember, useDefaultSetting, onlyUrls, hiddenAc } = data;
  255. if (isNaN(min) || isNaN(max)) {
  256. min = mi;
  257. max = inf;
  258. }
  259. if (min < mi) {
  260. min = mi;
  261. }
  262. if (max < min) {
  263. max = inf;
  264. }
  265. min = Number(min);
  266. max = Number(max);
  267. data.min = min;
  268. data.max = max;
  269. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_solution__"], data);
  270. for (let i = 0; i < A.length; i++) {
  271. if (!(A[i] instanceof HTMLAnchorElement)) {
  272. continue;
  273. }
  274. let d = (_a = A[i]) == null ? void 0 : _a.parentNode;
  275. if (!d) {
  276. continue;
  277. }
  278. let none = false;
  279. let Nohidden = isShow(d.textContent, min, max);
  280. d.style.display = Nohidden ? "" : "none";
  281. if (!Nohidden) {
  282. continue;
  283. }
  284. if (hiddenAc) {
  285. const svg = d.querySelector("svg");
  286. if (svg && svg.getAttribute("status")) {
  287. d.style.display = svg.getAttribute("status") == STATUS["AC"] ? "none" : "";
  288. }
  289. } else {
  290. d.style.display = "";
  291. }
  292. let c = d.textContent && d.textContent.indexOf("会员") != -1;
  293. if (!c) {
  294. continue;
  295. }
  296. d.style.display = visiableMember ? "" : "none";
  297. }
  298. } catch (e) {
  299. console.log("error", e);
  300. }
  301. }
  302. const initUrls = () => Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_update__"], true, Boolean.name) ? Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_urls__"], true, Array.name) : defaultUrls;
  303. const initObj = () => Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_solution__"]) ? Object.assign(defaultObj, Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_solution__"])) : defaultObj;
  304. const support_plugins = () => {
  305. const u = initObj();
  306. if (!u || !u.onlyUrls) return true;
  307. let url = window.location.href;
  308. if (isLeetCodeCircleUrl(url) && url.indexOf("view") != -1) {
  309. try {
  310. url = url.split("view")[0];
  311. } catch (e) {
  312. url = window.location.href;
  313. }
  314. }
  315. const urls = initUrls();
  316. for (let info of urls) {
  317. if (!info || !(info == null ? void 0 : info.link)) {
  318. continue;
  319. }
  320. if (info.link.indexOf(url) != -1) {
  321. return true;
  322. }
  323. }
  324. return false;
  325. };
  326. const defaultUrls = [
  327. {
  328. title: "链表、二叉树与一般树(前后指针/快慢指针/DFS/BFS/直径/LCA)",
  329. link: "https://leetcode.cn/circle/discuss/K0n2gO/"
  330. },
  331. {
  332. title: "贪心算法(基本贪心策略/反悔/区间/字典序/数学/思维/构造)",
  333. link: "https://leetcode.cn/circle/discuss/g6KTKL/"
  334. },
  335. {
  336. title: "滑动窗口(定长/不定长/多指针)",
  337. link: "https://leetcode.cn/circle/discuss/0viNMK/"
  338. },
  339. {
  340. title: "二分算法(二分答案/最小化最大值/最大化最小值/第K小)",
  341. link: "https://leetcode.cn/circle/discuss/SqopEo/"
  342. },
  343. {
  344. title: "单调栈(矩形面积/贡献法/最小字典序)",
  345. link: "https://leetcode.cn/circle/discuss/9oZFK9/"
  346. },
  347. {
  348. title: "网格图(DFS/BFS/综合应用)",
  349. link: "https://leetcode.cn/circle/discuss/YiXPXW/"
  350. },
  351. {
  352. title: "位运算(基础/性质/拆位/试填/恒等式/贪心/脑筋急转弯)",
  353. link: "https://leetcode.cn/circle/discuss/dHn9Vk/"
  354. },
  355. {
  356. title: "图论算法(DFS/BFS/拓扑排序/最短路/最小生成树/二分图/基环树/欧拉路径)",
  357. link: "https://leetcode.cn/circle/discuss/01LUak/"
  358. },
  359. {
  360. title: "动态规划(入门/背包/状态机/划分/区间/状压/数位/树形/数据结构优化)",
  361. link: "https://leetcode.cn/circle/discuss/tXLS3i/"
  362. },
  363. {
  364. title: "常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)",
  365. link: "https://leetcode.cn/circle/discuss/mOr1u6/"
  366. },
  367. {
  368. title: "数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)",
  369. link: "https://leetcode.cn/circle/discuss/IYT3ss/"
  370. }
  371. ];
  372. function getId(problemUrl) {
  373. if (isContest(problemUrl) || isProblem(problemUrl)) {
  374. try {
  375. return problemUrl.split("problems")[1].split("/")[1];
  376. } catch (e) {
  377. return "";
  378. }
  379. }
  380. return "";
  381. }
  382. function postData(ID) {
  383. return {
  384. "query": "\n query userQuestionStatus($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n status\n }\n}\n ",
  385. "variables": {
  386. "titleSlug": ID
  387. },
  388. "operationName": "userQuestionStatus"
  389. };
  390. }
  391. function queryStatus(ID = "", cache = {}, cur = void 0, watch2 = false) {
  392. if (!ID) {
  393. return;
  394. }
  395. if (cache[ID] == void 0 || cache[ID] != STATUS["AC"]) {
  396. fetch("https://leetcode.cn/graphql/", {
  397. method: "POST",
  398. credentials: "include",
  399. headers: {
  400. "Content-Type": "application/json"
  401. },
  402. body: JSON.stringify(postData(ID))
  403. }).then((res) => res.json()).then((response) => {
  404. var _a, _b, _c;
  405. if ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.question) {
  406. const status = (_c = (_b = response == null ? void 0 : response.data) == null ? void 0 : _b.question) == null ? void 0 : _c.status;
  407. if (cache[ID] == void 0 || cache[ID] != status) {
  408. cache[ID] = status == null ? "null" : status;
  409. if (watch2) {
  410. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_ac_key__"], cache);
  411. window.localStorage.setItem(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_status_update__"], JSON.stringify({
  412. "id": ID,
  413. "status": cache[ID]
  414. }));
  415. }
  416. createStatus(cache[ID], cur);
  417. }
  418. } else {
  419. console.log("query result is undefined");
  420. }
  421. }).catch((ignore) => {
  422. console.error("query status error : ", ignore);
  423. });
  424. }
  425. }
  426. function addProcess(reload = true, doms = void 0, asyncAc = false) {
  427. var _a;
  428. let problems_doms = Array.isArray(doms) ? doms : loadProblems();
  429. const cache = getLocalProblemStatus();
  430. for (let i = 0; i < problems_doms.length; i++) {
  431. let cur = problems_doms[i].parentElement;
  432. if (!(cur instanceof HTMLElement)) {
  433. continue;
  434. }
  435. const ID = getId((_a = problems_doms[i]) == null ? void 0 : _a.href);
  436. if (!ID) {
  437. continue;
  438. }
  439. if (install_pos()) {
  440. cur.style.listStyleType = "none";
  441. }
  442. if (!cache[ID] || cache[ID] != STATUS["AC"] && asyncAc) {
  443. queryStatus(ID, cache, cur, false);
  444. } else {
  445. let status = cache[ID];
  446. createStatus(status, cur);
  447. }
  448. }
  449. if (reload) {
  450. let cnt = 10;
  451. let timeId = setInterval(() => {
  452. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_ac_key__"], cache);
  453. cnt--;
  454. if (cnt == 0) {
  455. window.clearInterval(timeId);
  456. }
  457. }, 3e3);
  458. }
  459. }
  460. const submitProblems = (url = window.location.href, timeout = 500) => {
  461. const ID = getId(url);
  462. if (!ID) {
  463. return;
  464. }
  465. setTimeout(() => {
  466. const cache = getLocalProblemStatus();
  467. queryStatus(ID, cache, void 0, true);
  468. }, timeout);
  469. };
  470. const watchLinkStatusUpdate = (e) => {
  471. var _a;
  472. if (e.key != __0X3F_PROBLEM_KEYS__["__0x3f_problmes_status_update__"]) {
  473. return;
  474. }
  475. let { id, status } = JSON.parse(e.newValue);
  476. if (!id || !status) {
  477. return;
  478. }
  479. let thisLink = `https://leetcode.cn/problems/${id}`;
  480. let link = document.querySelector(`${linkCssSelector}[href^="https://leetcode.cn/problems/${id}"]`);
  481. if (!link || !(link == null ? void 0 : link.parentElement)) {
  482. let doms = loadProblems();
  483. for (let i = 0; i < doms.length; i++) {
  484. if (!doms[i] || !((_a = doms[i]) == null ? void 0 : _a.parentElement)) {
  485. continue;
  486. }
  487. if (doms[i].href.indexOf(thisLink) != -1) {
  488. link = doms[i];
  489. break;
  490. }
  491. }
  492. }
  493. createStatus(status, link);
  494. };
  495. function getProcess() {
  496. loadProblems();
  497. const cache = getLocalProblemStatus();
  498. let cnt = 0;
  499. for (let i = 0; i < A.length; i++) {
  500. let ID = getId(A[i].href);
  501. if (ID && cache[ID] == STATUS["AC"]) {
  502. cnt++;
  503. }
  504. }
  505. return [cnt, A.length];
  506. }
  507. function getLocalProblemStatus() {
  508. return Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_ac_key__"], true, Object.name);
  509. }
  510. const _hoisted_1 = { class: "processs-flex" };
  511. const _hoisted_2 = { style: { "text-align": "center", "color": "#121212" } };
  512. const _hoisted_3 = { class: "dialog-footer" };
  513. const formLabelWidth = "44px";
  514. const _sfc_main = {
  515. __name: "App",
  516. setup(__props) {
  517. let totProblem = vue.ref(0);
  518. let finishProblem = vue.ref(0);
  519. const drawer = vue.ref(false);
  520. const viewSetting = () => {
  521. drawer.value = !drawer.value;
  522. let [cur, tot] = getProcess();
  523. finishProblem.value = cur;
  524. totProblem.value = tot;
  525. };
  526. const finishProcess = vue.computed(() => {
  527. let p;
  528. try {
  529. const s = String(finishProblem.value / totProblem.value);
  530. let x1 = s.split(".")[1].padEnd(3).substring(0, 3);
  531. p = Math.min(100, Number(x1) / 10);
  532. } catch (e) {
  533. p = (finishProblem.value / totProblem.value).toFixed(3) * 100;
  534. }
  535. return isNaN(p) ? 0 : p;
  536. });
  537. const processColors = [
  538. { color: "#f56c6c", percentage: 20 },
  539. { color: "#1989fa", percentage: 40 },
  540. { color: "#e6a23c", percentage: 60 },
  541. { color: "#6f7ad3", percentage: 80 },
  542. { color: "#5cb87a", percentage: 100 }
  543. ];
  544. const fromData = vue.reactive(initObj());
  545. vue.watch(fromData, () => {
  546. handlerProblem(vue.toRaw(Object.assign({}, fromData)));
  547. });
  548. let tableData = vue.reactive(initUrls());
  549. const keywords = vue.ref("");
  550. const dialogTableVisible = vue.ref(false);
  551. const urlsData = vue.computed(() => tableData.filter((v) => v && v.title && v.title.indexOf(keywords.value) != -1));
  552. const isDisabbled = vue.computed(() => !!tableData.find((v) => (v == null ? void 0 : v.link) && (v == null ? void 0 : v.link.indexOf(window.location.href)) != -1));
  553. const dialogFormVisible = vue.ref(false);
  554. const info = vue.reactive({
  555. title: "",
  556. link: "",
  557. status: "add"
  558. });
  559. const addlocal = () => {
  560. if (!isDisabbled) {
  561. return;
  562. }
  563. tableData.unshift({ title: document.title, link: window.location.href });
  564. };
  565. const updateIndex = vue.ref(-1);
  566. const showProblems = () => {
  567. dialogTableVisible.value = true;
  568. let o = Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_add_cur__"]) == "true" || Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_add_cur__"]) == true;
  569. if (o) {
  570. addlocal();
  571. }
  572. };
  573. const handlerProblems = (status, updateInfo = { title: "", link: "" }, index = -1) => {
  574. dialogFormVisible.value = true;
  575. info.status = status;
  576. updateIndex.value = index;
  577. Object.assign(info, updateInfo);
  578. };
  579. const handlerMessage = (u, title, link) => {
  580. const a = u ? "添加" : "修改";
  581. const error = !title || !/https?:\/\/.*/.test(link);
  582. if (error) {
  583. ElementPlus.ElMessage.error(`${a} 失败 请保证标题或者链接有效 `);
  584. } else {
  585. ElementPlus.ElMessage.success(`${a} 成功 `);
  586. }
  587. return !error;
  588. };
  589. const addOrUpdate = () => {
  590. if (!handlerMessage(info.status == "add", info.title, info.link)) {
  591. return;
  592. }
  593. if (info.status == "add") {
  594. tableData.unshift({ title: info.title, link: info.link });
  595. } else {
  596. let index = updateIndex.value;
  597. if (index != -1 && index < tableData.length) {
  598. tableData[index].link = info.link;
  599. tableData[index].title = info.title;
  600. }
  601. }
  602. dialogFormVisible.value = false;
  603. };
  604. const deleteProblems = (index) => {
  605. tableData.splice(index, 1);
  606. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_urls__"], vue.toRaw(tableData));
  607. };
  608. const handlerDefault = () => {
  609. Message("确认使用默认题单,将会重置题单", () => {
  610. for (let i = 0; i < tableData.length; i++) {
  611. delete tableData[i];
  612. }
  613. for (let item of defaultUrls) {
  614. tableData.unshift(item);
  615. }
  616. ElementPlus.ElMessage({
  617. type: "success",
  618. message: "重置成功"
  619. });
  620. });
  621. };
  622. const asyncLocalStatus = () => {
  623. Message("确认同步题单", () => {
  624. addProcess(true, void 0, true);
  625. });
  626. };
  627. window.addEventListener("beforeunload", () => {
  628. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_urls__"], vue.toRaw(tableData).filter((u) => u != null && u != void 0));
  629. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_update__"], true);
  630. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_add_cur__"], false);
  631. });
  632. vue.onMounted(() => {
  633. if (support_plugins()) {
  634. let times = 30;
  635. let loadTimeId = setInterval(() => {
  636. let a = queryProblem();
  637. times--;
  638. if (Array.isArray(a) && a.length > 0) {
  639. handlerProblem(vue.toRaw(Object.assign({}, fromData)));
  640. addProcess();
  641. window.clearInterval(loadTimeId);
  642. }
  643. if (times == 0) {
  644. window.clearInterval(loadTimeId);
  645. }
  646. }, 200);
  647. window.addEventListener("storage", (e) => {
  648. watchLinkStatusUpdate(e);
  649. });
  650. }
  651. });
  652. const q1 = vue.ref(false);
  653. return (_ctx, _cache) => {
  654. const _component_el_button = vue.resolveComponent("el-button");
  655. const _component_el_progress = vue.resolveComponent("el-progress");
  656. const _component_el_divider = vue.resolveComponent("el-divider");
  657. const _component_el_input = vue.resolveComponent("el-input");
  658. const _component_el_col = vue.resolveComponent("el-col");
  659. const _component_el_form_item = vue.resolveComponent("el-form-item");
  660. const _component_el_switch = vue.resolveComponent("el-switch");
  661. const _component_el_tooltip = vue.resolveComponent("el-tooltip");
  662. const _component_el_form = vue.resolveComponent("el-form");
  663. const _component_el_dialog = vue.resolveComponent("el-dialog");
  664. const _component_el_row = vue.resolveComponent("el-row");
  665. const _component_el_link = vue.resolveComponent("el-link");
  666. const _component_el_table_column = vue.resolveComponent("el-table-column");
  667. const _component_el_table = vue.resolveComponent("el-table");
  668. const _component_el_drawer = vue.resolveComponent("el-drawer");
  669. return vue.openBlock(), vue.createElementBlock("div", null, [
  670. vue.createVNode(_component_el_button, {
  671. type: "primary",
  672. style: {},
  673. onClick: viewSetting,
  674. class: "m-setting-button m-button",
  675. circle: "",
  676. size: "large"
  677. }, {
  678. default: vue.withCtx(() => [
  679. vue.createTextVNode(" 0X3F ")
  680. ]),
  681. _: 1
  682. }),
  683. vue.createVNode(_component_el_drawer, {
  684. modelValue: drawer.value,
  685. "onUpdate:modelValue": _cache[17] || (_cache[17] = ($event) => drawer.value = $event),
  686. size: "30%",
  687. "with-header": false,
  688. style: { "position": "fixed !important" },
  689. direction: "rtl"
  690. }, {
  691. default: vue.withCtx(() => [
  692. vue.createElementVNode("div", _hoisted_1, [
  693. vue.createVNode(_component_el_progress, {
  694. type: "circle",
  695. percentage: finishProcess.value,
  696. color: processColors
  697. }, {
  698. default: vue.withCtx(({ percentage }) => [
  699. vue.createElementVNode("p", null, vue.toDisplayString(percentage) + "%", 1)
  700. ]),
  701. _: 1
  702. }, 8, ["percentage"])
  703. ]),
  704. vue.createElementVNode("p", _hoisted_2, vue.toDisplayString(vue.unref(finishProblem)) + " / " + vue.toDisplayString(vue.unref(totProblem)), 1),
  705. vue.createCommentVNode("", true),
  706. vue.createVNode(_component_el_divider),
  707. vue.createVNode(_component_el_form, {
  708. "label-position": "left",
  709. "label-width": "auto",
  710. model: fromData,
  711. style: { "max-width": "600px" }
  712. }, {
  713. default: vue.withCtx(() => [
  714. vue.createVNode(_component_el_form_item, { label: "分数区间" }, {
  715. default: vue.withCtx(() => [
  716. vue.createVNode(_component_el_col, { span: 10 }, {
  717. default: vue.withCtx(() => [
  718. vue.createVNode(_component_el_input, {
  719. modelValue: fromData.min,
  720. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => fromData.min = $event),
  721. "aria-placeholder": "",
  722. placeholder: " min "
  723. }, null, 8, ["modelValue"])
  724. ]),
  725. _: 1
  726. }),
  727. vue.createVNode(_component_el_col, {
  728. class: "text-center",
  729. span: 1,
  730. style: { "margin": "0 0.5rem" }
  731. }, {
  732. default: vue.withCtx(() => [
  733. vue.createTextVNode("-")
  734. ]),
  735. _: 1
  736. }),
  737. vue.createVNode(_component_el_col, { span: 10 }, {
  738. default: vue.withCtx(() => [
  739. vue.createVNode(_component_el_input, {
  740. modelValue: fromData.max,
  741. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => fromData.max = $event),
  742. "aria-placeholder": "",
  743. placeholder: " max"
  744. }, null, 8, ["modelValue"])
  745. ]),
  746. _: 1
  747. })
  748. ]),
  749. _: 1
  750. }),
  751. vue.createVNode(_component_el_form_item, { label: "显示会员题" }, {
  752. default: vue.withCtx(() => [
  753. vue.createVNode(_component_el_switch, {
  754. modelValue: fromData.visiableMember,
  755. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => fromData.visiableMember = $event)
  756. }, null, 8, ["modelValue"])
  757. ]),
  758. _: 1
  759. }),
  760. vue.createVNode(_component_el_form_item, { label: "隐藏AC题目" }, {
  761. default: vue.withCtx(() => [
  762. vue.createVNode(_component_el_switch, {
  763. modelValue: fromData.hiddenAc,
  764. "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => fromData.hiddenAc = $event)
  765. }, null, 8, ["modelValue"])
  766. ]),
  767. _: 1
  768. }),
  769. vue.createVNode(_component_el_form_item, { label: "收藏题单中生效" }, {
  770. default: vue.withCtx(() => [
  771. vue.createVNode(_component_el_tooltip, {
  772. content: "插件只在收藏题单中生效,刷新生效 ",
  773. placement: "bottom-end"
  774. }, {
  775. default: vue.withCtx(() => [
  776. vue.createVNode(_component_el_switch, {
  777. modelValue: fromData.onlyUrls,
  778. "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => fromData.onlyUrls = $event)
  779. }, null, 8, ["modelValue"])
  780. ]),
  781. _: 1
  782. })
  783. ]),
  784. _: 1
  785. }),
  786. vue.createVNode(_component_el_form_item, { label: "使用题单" }, {
  787. default: vue.withCtx(() => [
  788. vue.createVNode(_component_el_switch, {
  789. modelValue: fromData.useDefaultSetting,
  790. "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => fromData.useDefaultSetting = $event)
  791. }, null, 8, ["modelValue"])
  792. ]),
  793. _: 1
  794. })
  795. ]),
  796. _: 1
  797. }, 8, ["model"]),
  798. fromData.useDefaultSetting ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
  799. vue.createVNode(_component_el_divider),
  800. vue.createVNode(_component_el_button, {
  801. plain: "",
  802. onClick: asyncLocalStatus
  803. }, {
  804. default: vue.withCtx(() => [
  805. vue.createTextVNode(" 同步本页题目状态 ")
  806. ]),
  807. _: 1
  808. }),
  809. vue.createVNode(_component_el_button, {
  810. plain: "",
  811. onClick: showProblems
  812. }, {
  813. default: vue.withCtx(() => [
  814. vue.createTextVNode(" 查看收藏的题单 ")
  815. ]),
  816. _: 1
  817. }),
  818. vue.createVNode(_component_el_divider)
  819. ], 64)) : vue.createCommentVNode("", true),
  820. vue.createVNode(_component_el_button, {
  821. plain: "",
  822. onClick: _cache[8] || (_cache[8] = ($event) => q1.value = !q1.value)
  823. }, {
  824. default: vue.withCtx(() => [
  825. vue.createTextVNode(" 问题1 ")
  826. ]),
  827. _: 1
  828. }),
  829. vue.createVNode(_component_el_tooltip, { content: "此功能是为了多刷题单,重置题目状态,敬请期待!" }, {
  830. default: vue.withCtx(() => [
  831. vue.createVNode(_component_el_button, {
  832. plain: "",
  833. type: "warning",
  834. disabled: true
  835. }, {
  836. default: vue.withCtx(() => [
  837. vue.createTextVNode(" 题单重置 ")
  838. ]),
  839. _: 1
  840. })
  841. ]),
  842. _: 1
  843. }),
  844. vue.createVNode(_component_el_dialog, {
  845. modelValue: q1.value,
  846. "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => q1.value = $event),
  847. title: "关于查询状态会不会被封号 ?"
  848. }, {
  849. default: vue.withCtx(() => [
  850. vue.createVNode(Q1)
  851. ]),
  852. _: 1
  853. }, 8, ["modelValue"]),
  854. vue.createVNode(_component_el_dialog, {
  855. modelValue: dialogTableVisible.value,
  856. "onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => dialogTableVisible.value = $event),
  857. title: "题单"
  858. }, {
  859. default: vue.withCtx(() => [
  860. vue.createVNode(_component_el_row, { gutter: 10 }, {
  861. default: vue.withCtx(() => [
  862. vue.createVNode(_component_el_col, { span: 8 }, {
  863. default: vue.withCtx(() => [
  864. vue.createVNode(_component_el_input, {
  865. modelValue: keywords.value,
  866. "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => keywords.value = $event),
  867. placeholder: "请输入关键词过滤",
  868. clearable: ""
  869. }, null, 8, ["modelValue"])
  870. ]),
  871. _: 1
  872. }),
  873. vue.createVNode(_component_el_col, { span: 16 }, {
  874. default: vue.withCtx(() => [
  875. vue.createVNode(_component_el_button, {
  876. plain: "",
  877. onClick: addlocal,
  878. disabled: isDisabbled.value
  879. }, {
  880. default: vue.withCtx(() => [
  881. vue.createTextVNode(" 添加本页 ")
  882. ]),
  883. _: 1
  884. }, 8, ["disabled"]),
  885. vue.createVNode(_component_el_button, {
  886. plain: "",
  887. onClick: _cache[11] || (_cache[11] = ($event) => handlerProblems("add"))
  888. }, {
  889. default: vue.withCtx(() => [
  890. vue.createTextVNode(" 自定义 ")
  891. ]),
  892. _: 1
  893. }),
  894. vue.createVNode(_component_el_button, {
  895. plain: "",
  896. onClick: handlerDefault
  897. }, {
  898. default: vue.withCtx(() => [
  899. vue.createTextVNode(" 默认 ")
  900. ]),
  901. _: 1
  902. })
  903. ]),
  904. _: 1
  905. })
  906. ]),
  907. _: 1
  908. }),
  909. vue.createVNode(_component_el_table, {
  910. data: urlsData.value,
  911. height: "300",
  912. style: { "width": "100%", "margin-top": "10px" }
  913. }, {
  914. default: vue.withCtx(() => [
  915. vue.createVNode(_component_el_table_column, {
  916. label: "标题",
  917. width: "auto",
  918. align: "center"
  919. }, {
  920. default: vue.withCtx((scope) => [
  921. vue.createVNode(_component_el_link, {
  922. href: scope.row.link,
  923. target: "_blank",
  924. type: "default"
  925. }, {
  926. default: vue.withCtx(() => [
  927. vue.createTextVNode(vue.toDisplayString(scope.row.title), 1)
  928. ]),
  929. _: 2
  930. }, 1032, ["href"])
  931. ]),
  932. _: 1
  933. }),
  934. vue.createVNode(_component_el_table_column, {
  935. label: "操作",
  936. width: "auto",
  937. align: "center"
  938. }, {
  939. default: vue.withCtx((scope) => [
  940. vue.createVNode(_component_el_button, {
  941. type: "primary",
  942. size: "small",
  943. onClick: ($event) => handlerProblems("update", scope.row, scope.$index)
  944. }, {
  945. default: vue.withCtx(() => [
  946. vue.createTextVNode("编辑")
  947. ]),
  948. _: 2
  949. }, 1032, ["onClick"]),
  950. vue.createVNode(_component_el_button, {
  951. type: "danger",
  952. size: "small",
  953. onClick: ($event) => deleteProblems(scope.$index)
  954. }, {
  955. default: vue.withCtx(() => [
  956. vue.createTextVNode("删除")
  957. ]),
  958. _: 2
  959. }, 1032, ["onClick"])
  960. ]),
  961. _: 1
  962. })
  963. ]),
  964. _: 1
  965. }, 8, ["data"])
  966. ]),
  967. _: 1
  968. }, 8, ["modelValue"]),
  969. vue.createVNode(_component_el_dialog, {
  970. modelValue: dialogFormVisible.value,
  971. "onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => dialogFormVisible.value = $event),
  972. title: `${info.status == "add" ? "添加" : "编辑"}`,
  973. width: "400"
  974. }, {
  975. footer: vue.withCtx(() => [
  976. vue.createElementVNode("div", _hoisted_3, [
  977. vue.createVNode(_component_el_button, {
  978. onClick: _cache[15] || (_cache[15] = ($event) => dialogFormVisible.value = false)
  979. }, {
  980. default: vue.withCtx(() => [
  981. vue.createTextVNode("取消")
  982. ]),
  983. _: 1
  984. }),
  985. vue.createVNode(_component_el_button, {
  986. type: "primary",
  987. onClick: addOrUpdate
  988. }, {
  989. default: vue.withCtx(() => [
  990. vue.createTextVNode(" 确认 ")
  991. ]),
  992. _: 1
  993. })
  994. ])
  995. ]),
  996. default: vue.withCtx(() => [
  997. vue.createVNode(_component_el_form, null, {
  998. default: vue.withCtx(() => [
  999. vue.createVNode(_component_el_form_item, {
  1000. label: "标题",
  1001. "label-width": formLabelWidth
  1002. }, {
  1003. default: vue.withCtx(() => [
  1004. vue.createVNode(_component_el_input, {
  1005. modelValue: info.title,
  1006. "onUpdate:modelValue": _cache[13] || (_cache[13] = ($event) => info.title = $event),
  1007. autocomplete: "off"
  1008. }, null, 8, ["modelValue"])
  1009. ]),
  1010. _: 1
  1011. }),
  1012. vue.createVNode(_component_el_form_item, {
  1013. label: "链接",
  1014. "label-width": formLabelWidth
  1015. }, {
  1016. default: vue.withCtx(() => [
  1017. vue.createVNode(_component_el_input, {
  1018. modelValue: info.link,
  1019. "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => info.link = $event),
  1020. autocomplete: "off"
  1021. }, null, 8, ["modelValue"])
  1022. ]),
  1023. _: 1
  1024. })
  1025. ]),
  1026. _: 1
  1027. })
  1028. ]),
  1029. _: 1
  1030. }, 8, ["modelValue", "title"])
  1031. ]),
  1032. _: 1
  1033. }, 8, ["modelValue"])
  1034. ]);
  1035. };
  1036. }
  1037. };
  1038. const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-3dc7143a"]]);
  1039. const cssLoader = (e) => {
  1040. const t = GM_getResourceText(e);
  1041. return GM_addStyle(t), t;
  1042. };
  1043. cssLoader("elementPlusCss");
  1044. const stopRankingKey = "__is_stop_rating_ranking__";
  1045. let conetstTimeId = null;
  1046. function run$1() {
  1047. const container = document.querySelector(".contest-question-info .list-group");
  1048. if (!container) return;
  1049. const ls = Array.from(container.querySelectorAll(".list-group-item .pull-right"));
  1050. for (let i = 0; i < 4; i++) {
  1051. if (i >= ls.length) {
  1052. break;
  1053. }
  1054. if (ls[i] instanceof HTMLElement) {
  1055. ls[i].textContent = "0";
  1056. }
  1057. }
  1058. window.clearInterval(conetstTimeId);
  1059. }
  1060. function startStopRanking() {
  1061. if (!isContest(window.location.href)) {
  1062. return;
  1063. }
  1064. const isNext = !!document.querySelector("#__next");
  1065. if (isNext) {
  1066. return;
  1067. }
  1068. const use = Cache$1.get(stopRankingKey);
  1069. if (use) {
  1070. conetstTimeId = setInterval(() => {
  1071. run$1();
  1072. }, 10);
  1073. }
  1074. _GM_registerMenuCommand(`${use ? "使用" : "关闭"} 排行榜`, () => {
  1075. Cache$1.set(stopRankingKey, !use);
  1076. window.location.reload();
  1077. }, { title: "对于不想看到排行榜的可以使用此功能 默认开启" });
  1078. }
  1079. const local_url = window.location.href;
  1080. let loadID = 0;
  1081. let submitCnt = 0;
  1082. function watchDom(dom) {
  1083. if (!(dom instanceof HTMLElement)) {
  1084. return;
  1085. }
  1086. let m = new MutationObserver(() => {
  1087. if (submitCnt % 2 == 1) {
  1088. submitProblems(local_url);
  1089. }
  1090. submitCnt++;
  1091. });
  1092. m.observe(dom, {
  1093. childList: true,
  1094. attributes: true
  1095. });
  1096. }
  1097. function run() {
  1098. loadID++;
  1099. if (isProblem(local_url) || isContest(local_url)) {
  1100. if (isProblem(local_url) && loadID == 1) {
  1101. submitProblems(local_url);
  1102. }
  1103. setTimeout(() => {
  1104. let submitbutton = null;
  1105. const isNext = !!document.querySelector("#__next");
  1106. if (isProblem(local_url) || isNext) {
  1107. submitbutton = document.querySelector("div [data-e2e-locator=console-submit-button]");
  1108. } else {
  1109. let buttons = Array.from(document.querySelectorAll(".question-detail-bottom .pull-right button"));
  1110. for (let i = buttons.length - 1; i >= 0; i--) {
  1111. if (buttons[i].textContent.indexOf("提交解答") != -1) {
  1112. submitbutton = buttons[i];
  1113. break;
  1114. }
  1115. }
  1116. }
  1117. if (submitbutton) {
  1118. submitbutton.addEventListener("click", () => {
  1119. submitProblems(local_url, 10 * 1e3);
  1120. });
  1121. watchDom(submitbutton);
  1122. } else if (loadID < 10) {
  1123. run();
  1124. }
  1125. }, 3e3);
  1126. } else if (isLeetCodeCircleUrl(local_url)) {
  1127. let Container = null;
  1128. let ok = Cache$1.get(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_button_is_none__"], true, Boolean.name);
  1129. const start = () => {
  1130. Container = document.createElement("div");
  1131. const body = document.querySelector("body");
  1132. body.append(Container);
  1133. Container.style.display = ok && support_plugins() ? "block" : "none";
  1134. return Container;
  1135. };
  1136. let dom = start();
  1137. const VueApp = vue.createApp(App);
  1138. _GM_registerMenuCommand(`${ok ? "隐藏按钮" : "显示按钮"}`, () => {
  1139. ok = !ok;
  1140. Container.style.display = ok ? "block" : "none";
  1141. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_button_is_none__"], ok);
  1142. }, { title: "可以手动关闭或者显示按钮 默认显示 刷新生效" });
  1143. _GM_registerMenuCommand(`安装到${install_pos() ? "右侧" : "左侧"}`, () => {
  1144. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_insert_pos__"], install_pos());
  1145. window.location.reload();
  1146. }, { title: "AC标记安装位置,默认左侧,刷新生效" });
  1147. _GM_registerMenuCommand(`清空题目状态缓存`, () => {
  1148. Message("确认清空题目状态缓存", () => {
  1149. Cache$1.remove(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_ac_key__"]);
  1150. window.location.reload();
  1151. });
  1152. }, { title: "如果题目状态出现问题,可以试试,一般情况下不建议使用" });
  1153. _GM_registerMenuCommand(`同步题目状态`, () => {
  1154. Message("确认同步题目状态", () => {
  1155. addProcess(true, void 0, true);
  1156. });
  1157. }, { title: "如果不在同一个浏览器答题,或者关闭了改插件,会出现ac题目状态没有及时同步,可以使用此功能" });
  1158. _GM_registerMenuCommand(`${initObj().onlyUrls ? "仅在收藏题单页面生效" : "所有题单生效"}`, () => {
  1159. const u = initObj();
  1160. u.onlyUrls = !u.onlyUrls;
  1161. Container.style.display = support_plugins() ? "block" : "none";
  1162. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_solution__"], u);
  1163. }, { title: "插件默认会在所有讨论发布页生效,如果只想在收藏链接生效,可以使用此功能" });
  1164. _GM_registerMenuCommand(`添加本页`, () => {
  1165. const urls = initUrls();
  1166. let ok2 = false;
  1167. let url = window.location.href;
  1168. for (let info of urls) {
  1169. if (!info || !(info == null ? void 0 : info.link)) {
  1170. continue;
  1171. }
  1172. if (info.link.indexOf(url) != -1) {
  1173. ok2 = true;
  1174. break;
  1175. }
  1176. }
  1177. if (ok2) {
  1178. ElementPlus.ElMessage({
  1179. message: "收藏失败,链接已经存在!",
  1180. type: "error"
  1181. });
  1182. } else {
  1183. if (isLeetCodeCircleUrl(url) && url.indexOf("view") != -1) {
  1184. try {
  1185. url = url.split("view")[0];
  1186. } catch (e) {
  1187. url = window.location.href;
  1188. }
  1189. }
  1190. urls.unshift({
  1191. title: document.title,
  1192. link: url
  1193. });
  1194. Container.style.display = "block";
  1195. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_urls__"], urls);
  1196. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_update__"], true);
  1197. Cache$1.set(__0X3F_PROBLEM_KEYS__["__0x3f_problmes_add_cur__"], true);
  1198. ElementPlus.ElMessage({
  1199. message: "收藏成功!刷新生效",
  1200. type: "success"
  1201. });
  1202. }
  1203. });
  1204. VueApp.use(ElementPlus).mount(dom);
  1205. }
  1206. }
  1207. run();
  1208. startStopRanking();
  1209.  
  1210. })(Vue, ElementPlus);