palicanon.js 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439
  1. var _lang = "";
  2. var _langsetting = "";
  3. var _channelType = "translation";
  4. var _progress = 0.9;
  5. var _view = "community";
  6. var main_tag = "";
  7. var list_tag = new Array();
  8. var currTagLevel0 = new Array();
  9. var allTags = new Array();
  10. var arrMyTerm = new Array();
  11. var _listView = "list";
  12. var gBreadCrumbs = ["", "", "", "", "", "", "", "", ""];
  13. var _nextPageStart = 0;
  14. var _pageSize = 20;
  15. var _channel = "";
  16. var _palicanonCategory, _palicanonCategoryCurrent, _palicanonCategoryPath;
  17. var _tags = "";
  18. var _channelList;
  19. palicanon_load_term();
  20. function getLangSetting(setting) {
  21. switch (setting) {
  22. case "auto":
  23. switch (getCookie("language")) {
  24. case "zh-cn":
  25. return "zh";
  26. break;
  27. case "zh-tw":
  28. return "zh";
  29. break;
  30. case "":
  31. return "";
  32. break;
  33. }
  34. break;
  35. default:
  36. return setting;
  37. break;
  38. }
  39. }
  40. function updateSetting() {
  41. _langsetting = $("#setting_lang").val();
  42. _lang = getLangSetting(_langsetting);
  43. _channelType = $("#setting_channel_type").val();
  44. _progress = $("#setting_progress").val();
  45. localStorage.setItem(
  46. "pc_filter_setting",
  47. JSON.stringify({
  48. lang: _lang,
  49. lang_setting: $("#setting_lang").val(),
  50. channel_type: _channelType,
  51. progress: _progress,
  52. })
  53. );
  54. switch (_view) {
  55. case "community":
  56. _nextPageStart = 0;
  57. LoadAllChannel();
  58. communityGetChapter();
  59. break;
  60. case "category":
  61. break;
  62. default:
  63. break;
  64. }
  65. }
  66. /*
  67. 载入过滤器设置
  68. */
  69. function loadFilterSetting() {
  70. if (localStorage.getItem("pc_filter_setting")) {
  71. let setting = JSON.parse(localStorage.getItem("pc_filter_setting"));
  72. _langsetting = setting.lang_setting;
  73. _lang = getLangSetting(_langsetting);
  74. _channel_type = setting.channel_type;
  75. _progress = setting.progress;
  76. }
  77. _nextPageStart = 0;
  78. }
  79. function community_onload() {
  80. $("#main_view").addClass("community");
  81. render_selected_filter_list();
  82. communityGetChapter();
  83. LoadAllChannel();
  84. LoadAllLanguage();
  85. }
  86. function palicanon_onload() {
  87. $("#main_view").addClass("category");
  88. LoadAllChannel();
  89. LoadAllLanguage();
  90. }
  91. function palicanon_load_term() {
  92. let lang = getCookie("language");
  93. switch (lang) {
  94. case "zh-cn":
  95. lang = "zh-hans";
  96. break;
  97. case "zh-tw":
  98. lang = "zh-hant";
  99. break;
  100. case "":
  101. lang = "en";
  102. break;
  103. }
  104. $.get(
  105. "/api/v2/terms",
  106. {
  107. view: "hot-meaning",
  108. language: lang,
  109. },
  110. function (data) {
  111. if (data.ok) {
  112. arrMyTerm = data.data.rows;
  113. } else {
  114. alert(data.message);
  115. }
  116. }
  117. );
  118. }
  119. function tag_changed() {
  120. _nextPageStart = 0;
  121. let strTags = "";
  122. if (list_tag.length > 0) {
  123. _tags = list_tag.join();
  124. } else {
  125. _tags = "";
  126. }
  127. console.log(_tags);
  128. let lang = getCookie("language");
  129. switch (lang) {
  130. case "zh-cn":
  131. lang = "zh-hans";
  132. break;
  133. case "zh-tw":
  134. lang = "zh-hant";
  135. break;
  136. case "":
  137. lang = "en";
  138. break;
  139. }
  140. switch (_view) {
  141. case "community":
  142. communityGetChapter();
  143. break;
  144. case "category":
  145. if (_tags == "") {
  146. updatePalicanonCategoryList();
  147. $("#palicanon-category").show();
  148. $("#chapter_shell").hide();
  149. } else {
  150. $("#palicanon-category").hide();
  151. $("#chapter_shell").show();
  152. palicanonGetChapter(_tags, lang);
  153. }
  154. break;
  155. case "my":
  156. break;
  157. default:
  158. break;
  159. }
  160. gBreadCrumbs = ["", "", "", "", "", "", "", "", ""];
  161. RenderBreadCrumbs();
  162. updataHistory();
  163. }
  164. function updataHistory() {
  165. let url = "?view=" + _view;
  166. if (_tags !== "") {
  167. url += "&tag=" + _tags;
  168. }
  169. if (_channel !== "") {
  170. url += "&channel=" + _channel;
  171. }
  172. history.pushState(
  173. { view: _view, tag: _tags, channel: _channel },
  174. "title",
  175. url
  176. );
  177. }
  178. function communityGetChapter(offset = 0) {
  179. next_page_loader_show();
  180. let param = {
  181. tags: _tags,
  182. lang: _lang,
  183. channel: _channel,
  184. channel_type: _channelType,
  185. offset: offset,
  186. };
  187. console.log("查询条件", param);
  188. $.getJSON("/api/v2/progress?view=chapter", param)
  189. .done(function (data, status) {
  190. $("#filter_bar_left").html(data.data.count + "个章节");
  191. let arrChapterData = data.data.rows;
  192. let arrChapterList = new Array();
  193. let html = "";
  194. allTags = new Array();
  195. let arrChapter = new Array();
  196. for (const iterator of arrChapterData) {
  197. arrChapterList.push({
  198. book: iterator.book,
  199. para: iterator.para,
  200. level: 2,
  201. title: iterator.toc,
  202. progress: { lang: "en", all_trans: iterator.progress },
  203. tag: "",
  204. trans_title: iterator.title,
  205. channel_id: iterator.channel_id,
  206. type: "article",
  207. channel_info: iterator.channel,
  208. path: JSON.parse(iterator.path),
  209. views: iterator.views,
  210. likes: iterator.likes,
  211. tags: iterator.tags,
  212. summary: iterator.summary,
  213. created_at: iterator.created_at,
  214. });
  215. }
  216. for (const iterator of arrChapterList) {
  217. arrChapter.push(iterator);
  218. }
  219. if (_nextPageStart == 0) {
  220. palicanon_chapter_list_apply(0);
  221. $("#list-1").html(render_chapter_list(arrChapter));
  222. } else {
  223. $("#list-1").append(render_chapter_list(arrChapter));
  224. }
  225. next_page_loader_hide();
  226. })
  227. .fail(function (jqXHR, textStatus, errorThrown) {
  228. switch (jqXHR.status) {
  229. case 404:
  230. $("#list-1").html("未找到");
  231. next_page_loader_hide();
  232. break;
  233. case 500:
  234. console.error("/api/v2/progress?view=chapter", textStatus);
  235. break;
  236. default:
  237. break;
  238. }
  239. });
  240. communityLoadChapterTag();
  241. }
  242. function communityLoadChapterTag(strTags = "", lang = "") {
  243. $.getJSON(
  244. "/api/v2/progress?view=chapter-tag",
  245. {
  246. tags: _tags,
  247. lang: _lang,
  248. channel: _channel,
  249. },
  250. function (data, status) {
  251. let tagData = data.data.rows;
  252. allTags = new Array();
  253. let maxCount = tagData[0].count;
  254. for (const tag of tagData) {
  255. if (tag.count < maxCount) {
  256. allTags[tag.name] = tag.count;
  257. }
  258. }
  259. tag_render_others();
  260. }
  261. );
  262. }
  263. function palitextGetChapter(strTags = "") {
  264. if (_tags == "") {
  265. return;
  266. }
  267. $.getJSON("/api/v2/palitext?view=chapter", {
  268. tags: _tags,
  269. })
  270. .done(function (data, status) {
  271. let arrChapterData = data.data.rows;
  272. let arrChapterList = new Array();
  273. let arrChapter = new Array();
  274. let lastParent = -1;
  275. for (let index = 0; index < arrChapterData.length; index++) {
  276. arrChapterData[index].children = new Array();
  277. }
  278. for (const it of arrChapterData) {
  279. if (arrChapterList.length == 0) {
  280. arrChapterList.push(it);
  281. continue;
  282. }
  283. if (lastParent >= 0) {
  284. //判断是否为这个章节的子章节
  285. if (
  286. arrChapterList[lastParent].book == it.book &&
  287. arrChapterList[lastParent].paragraph == it.parent
  288. ) {
  289. arrChapterList[lastParent].children.push(it);
  290. } else {
  291. arrChapterList.push(it);
  292. lastParent = -1;
  293. }
  294. } else {
  295. //判断是否为最末尾章节的子章节
  296. if (
  297. arrChapterList[arrChapterList.length - 1].book ==
  298. it.book &&
  299. arrChapterList[arrChapterList.length - 1].paragraph ==
  300. it.parent
  301. ) {
  302. lastParent = arrChapterList.length - 1;
  303. arrChapterList[arrChapterList.length - 1].children.push(
  304. it
  305. );
  306. } else {
  307. arrChapterList.push(it);
  308. }
  309. }
  310. }
  311. palicanon_chapter_list_apply(0);
  312. $("#list-1").html(render_chapter_list(arrChapterList));
  313. })
  314. .fail(function (jqXHR, textStatus, errorThrown) {
  315. switch (jqXHR.status) {
  316. case 404:
  317. $("#list-1").html("未找到");
  318. next_page_loader_hide();
  319. break;
  320. case 500:
  321. console.error("/api/v2/progress?view=chapter", textStatus);
  322. break;
  323. default:
  324. break;
  325. }
  326. });
  327. palitextLoadChapterTag(strTags);
  328. }
  329. function palitextLoadChapterTag(strTags = "") {
  330. $.getJSON(
  331. "/api/v2/palitext?view=chapter-tag",
  332. {
  333. tags: strTags,
  334. },
  335. function (data, status) {
  336. let tagData = data.data.rows;
  337. allTags = new Array();
  338. let maxCount = tagData[0].count;
  339. for (const tag of tagData) {
  340. if (tag.count < maxCount) {
  341. allTags[tag.name] = tag.count;
  342. }
  343. }
  344. tag_render_others();
  345. }
  346. );
  347. }
  348. function palicanonGetChapter(strTags, lang) {
  349. palitextGetChapter(strTags);
  350. }
  351. function viewChanged(obj) {
  352. _listView = $(obj).val();
  353. updateFirstListView();
  354. }
  355. function updateFirstListView() {
  356. if (_listView == "list") {
  357. $("#list_shell_1").removeClass("book_view");
  358. $("#list_shell_1").addClass("list_view");
  359. } else {
  360. $("#list_shell_1").addClass("book_view");
  361. $("#list_shell_1").removeClass("list_view");
  362. }
  363. }
  364. function palicanon_load_chapter(book, para, div_index = 1) {
  365. let lang = getCookie("language");
  366. if (lang == "zh-cn") {
  367. lang = "zh-hans";
  368. } else if (lang == "zh-tw") {
  369. lang = "zh-hant";
  370. } else if (lang == "") {
  371. lang = "en";
  372. }
  373. $.get(
  374. "../palicanon/get_chapter_info.php",
  375. {
  376. book: book,
  377. para: para,
  378. lang: lang,
  379. },
  380. function (data, status) {
  381. palicanon_chapter_list_apply(div_index);
  382. let arrChapterInfo = JSON.parse(data);
  383. let html = render_chapter_head(arrChapterInfo, div_index);
  384. $("#chapter_head_" + (parseInt(div_index) + 1)).html(html);
  385. let lang = getCookie("language");
  386. if (lang == "zh-cn") {
  387. lang = "zh-hans";
  388. } else if (lang == "zh-tw") {
  389. lang = "zh-hant";
  390. } else if (lang == "") {
  391. lang = "en";
  392. }
  393. $.get(
  394. "./get_chapter_children.php",
  395. {
  396. book: book,
  397. para: para,
  398. lang: lang,
  399. },
  400. function (data, status) {
  401. let arrChapterList = JSON.parse(data);
  402. $("#list-" + (parseInt(div_index) + 1)).html(
  403. render_chapter_list(arrChapterList)
  404. );
  405. }
  406. );
  407. //获取章节的channel列表
  408. loadChapterChannel({
  409. book: book,
  410. para: para,
  411. readonly: true,
  412. target: $("#chapter_head_" + (parseInt(div_index) + 1))
  413. .find(".progress")
  414. .first(),
  415. });
  416. }
  417. );
  418. }
  419. function render_chapter_head(chapter_info, parent) {
  420. let html = "";
  421. html = "<div class='chapter_head_tool_bar'>";
  422. html +=
  423. "<div><span class='chapter_back_button' id='chapter_back_" +
  424. (parent + 1) +
  425. "' onclick=\"chapter_back('" +
  426. parent +
  427. "')\">back</span></div>";
  428. html +=
  429. "<div><button class='chapter_close_button' id='chapter_close_" +
  430. (parent + 1) +
  431. "' onclick=\"chapter_back('" +
  432. parent +
  433. "')\">⬅</button></div>";
  434. html += "</div>";
  435. let link =
  436. "../reader/?view=chapter&book=" +
  437. chapter_info.book +
  438. "&par=" +
  439. chapter_info.paragraph;
  440. html += "<div class='title'>";
  441. let sToc = chapter_info.toc;
  442. html += " <div class='title_1'>";
  443. if (typeof chapter_info.trans_title == "undefined") {
  444. html += "<a href='" + link + "' target='_blank'>";
  445. if (sToc == "") {
  446. html += "[unnamed]";
  447. } else {
  448. switch (getCookie("language")) {
  449. case "my":
  450. html += roman_to_my(sToc);
  451. break;
  452. case "si":
  453. html += roman_to_si(sToc);
  454. break;
  455. default:
  456. html += sToc;
  457. break;
  458. }
  459. }
  460. html += "</a>";
  461. } else {
  462. html +=
  463. "<a href='" +
  464. link +
  465. "' target='_blank'>" +
  466. chapter_info.trans_title +
  467. "</a>";
  468. }
  469. html += "</div>";
  470. html += "<div class='title_2'>" + sToc + "</div>";
  471. html += "</div>";
  472. html += "<div class='res res_more'>";
  473. html += "<h2>译文</h2>";
  474. html += "<div class='progress' id='chapter_progress'>";
  475. if (chapter_info.progress && chapter_info.progress.length > 0) {
  476. let r = 12;
  477. let perimeter = 2 * Math.PI * r;
  478. for (const iterator of chapter_info.progress) {
  479. let stroke1 = parseInt(perimeter * iterator.all_trans);
  480. let stroke2 = perimeter - stroke1;
  481. html += ' <div class="item">';
  482. html +=
  483. '<svg class="progress_circle" width="30" height="30" viewbox="0,0,30,30">';
  484. html +=
  485. '<circle class="progress_bg" cx="15" cy="15" r="12" stroke-width="5" fill="none"></circle>';
  486. html +=
  487. '<circle class="progress_color" cx="15" cy="15" r="12" stroke-width="5" fill="none" stroke-dasharray="' +
  488. stroke1 +
  489. " " +
  490. stroke2 +
  491. '"></circle>';
  492. html += "</svg>";
  493. html +=
  494. "<div class='lang'>" +
  495. iterator.lang +
  496. "-" +
  497. parseInt(iterator.all_trans * 100) +
  498. "%</div>";
  499. html += " </div>";
  500. }
  501. } else {
  502. html += "无译文";
  503. }
  504. html += "</div>";
  505. html += "</div>";
  506. return html;
  507. }
  508. function render_chapter_list(chapterList) {
  509. let html = "";
  510. for (const iterator of chapterList) {
  511. html += palicanon_render_chapter_row(iterator);
  512. }
  513. return html;
  514. }
  515. function isChapterWithParent(list, item) {}
  516. function palicanon_chapter_list_apply(div_index) {
  517. let iDiv = parseInt(div_index);
  518. let html = "";
  519. html +=
  520. "<div id='chapter_head_" + (iDiv + 1) + "' class='chapter_head'></div>";
  521. html +=
  522. "<ul id='list-" +
  523. (iDiv + 1) +
  524. "' class='grid' level='" +
  525. (iDiv + 1) +
  526. "'>";
  527. html += "</ul>";
  528. html += "<div id='more_chapter'>";
  529. html +=
  530. '<div id="page_loader" class="lds-ellipsis" style="visibility: hidden;"><div></div><div></div><div></div><div></div></div>';
  531. html += "<div id='more_chapter_line'></div>";
  532. html += "<button id='btn_more_chapter' onclick='next_page()'>More</button>";
  533. html += "</div>";
  534. $("#list_shell_" + (iDiv + 1)).html(html);
  535. $("#list_shell_" + (iDiv + 1)).removeClass();
  536. $("#list_shell_" + (iDiv + 1)).addClass("show");
  537. //隐藏之后的列表
  538. for (let index = iDiv + 2; index <= 8; index++) {
  539. $("#list_shell_" + index).removeClass();
  540. $("#list_shell_" + index).addClass("hidden");
  541. }
  542. //收缩当前的
  543. $("#list-" + iDiv).removeClass();
  544. $("#list-" + iDiv).addClass("list");
  545. $("#list_shell_" + iDiv).removeClass();
  546. $("#list_shell_" + iDiv).addClass("list");
  547. updateFirstListView();
  548. }
  549. function next_page_loader_show() {
  550. $("#page_loader").css("visibility", "visible");
  551. }
  552. function next_page_loader_hide() {
  553. $("#page_loader").css("visibility", "hidden");
  554. }
  555. function next_page() {
  556. _nextPageStart += _pageSize;
  557. communityGetChapter(_nextPageStart);
  558. }
  559. function chapter_onclick(obj) {
  560. let objList = $(obj).parent().parent().parent().parent().parent();
  561. let book = $(objList).attr("book");
  562. let para = $(objList).attr("para");
  563. let channel = $(objList).attr("channel");
  564. let type = $(objList).attr("type");
  565. let level = parseInt($(objList).parent().attr("level"));
  566. let title1 = $(objList).find(".title_1").first().text();
  567. if (_view == "category" && level == 1) {
  568. $("#index_div").addClass("popup");
  569. }
  570. if (type == "article") {
  571. window.open(
  572. "../article/index.php?view=chapter&book=" +
  573. book +
  574. "&par=" +
  575. para +
  576. "&channel=" +
  577. channel
  578. );
  579. } else {
  580. gBreadCrumbs[level] = {
  581. title1: title1,
  582. book: book,
  583. para: para,
  584. level: level,
  585. };
  586. RenderBreadCrumbs();
  587. $(objList).siblings().removeClass("selected");
  588. $(objList).addClass("selected");
  589. $("#tag_list").slideUp();
  590. palicanon_load_chapter(book, para, level);
  591. }
  592. }
  593. function close_tag_list() {
  594. $("#tag_list").slideUp();
  595. $("#btn-filter").removeClass("active");
  596. }
  597. function renderProgress(progress = 0, width = 16, height = 16) {
  598. //绘制进度圈
  599. let r = 12;
  600. let perimeter = 2 * Math.PI * r;
  601. let stroke1 = parseInt(perimeter * progress);
  602. let stroke2 = perimeter - stroke1;
  603. let html = "";
  604. html +=
  605. '<svg class="progress_circle" width="16" height="16" viewbox="0,0,30,30">';
  606. html +=
  607. '<circle class="progress_bg" cx="15" cy="15" r="12" stroke-width="5" fill="none"></circle>';
  608. html +=
  609. '<circle class="progress_color" cx="15" cy="15" r="12" stroke-width="5" fill="none" stroke-dasharray="' +
  610. stroke1 +
  611. " " +
  612. stroke2 +
  613. '"></circle>';
  614. html += "</svg>";
  615. return html;
  616. }
  617. function palicanon_render_chapter_row(chapter, isSub = false) {
  618. let html = "";
  619. let levelClass = "";
  620. if (chapter.level == 1) {
  621. //levelClass = " level_1";
  622. }
  623. let para = 0;
  624. if (chapter.para) {
  625. para = chapter.para;
  626. } else if (chapter.paragraph) {
  627. para = chapter.paragraph;
  628. }
  629. html +=
  630. '<li class="' +
  631. levelClass +
  632. '" book="' +
  633. chapter.book +
  634. '" para="' +
  635. para +
  636. '"';
  637. if (typeof chapter.type !== "undefined" && chapter.type === "article") {
  638. html +=
  639. ' channel="' + chapter.channel_id + '" type="' + chapter.type + '"';
  640. }
  641. html += " >";
  642. html += '<div class="main">';
  643. html += '<div class="left">';
  644. html += "<div class='left_items'>";
  645. if (typeof chapter.views != "undefined") {
  646. html += "<div class='left_item'>";
  647. html += "<span class='item'>";
  648. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  649. html +=
  650. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#eye'>";
  651. html += "</svg>";
  652. html += "<span class='text'>";
  653. html += chapter.views;
  654. html += "</span>";
  655. html += "</span>";
  656. html += "</div>";
  657. }
  658. if (typeof chapter.likes != "undefined") {
  659. html += "<div class='left_item'>";
  660. html += "<span class='item'>";
  661. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  662. html +=
  663. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#heart'>";
  664. html += "</svg>";
  665. html += "<span class='text'>";
  666. html += chapter.likes;
  667. html += "</span>";
  668. html += "</span>";
  669. html += "</div>";
  670. }
  671. //完成度
  672. if (chapter.progress && chapter.progress.all_trans) {
  673. html += "<div class='left_item'>";
  674. html += "<span class='item'>";
  675. html += renderProgress(chapter.progress.all_trans);
  676. html += "<span class='text'>";
  677. if (chapter.progress) {
  678. html += parseInt(chapter.progress.all_trans * 100 + 1) + "%";
  679. } else {
  680. html += "无";
  681. }
  682. html += "</span>";
  683. html += "</span>";
  684. html += "</div>";
  685. }
  686. html += "<div class='left_item'></div>";
  687. html += "</div>"; //end of left_items
  688. html += "<div class='chapter_icon'>";
  689. html += '<span class="" style="margin-right: 1em;padding: 4px 0;">';
  690. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  691. if (typeof chapter.type !== "undefined" && chapter.type === "article") {
  692. html +=
  693. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#journal-text'>";
  694. } else {
  695. if (chapter.level == 1) {
  696. html +=
  697. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#journal'>";
  698. } else {
  699. html +=
  700. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#folder2-open'>";
  701. }
  702. }
  703. html += "</svg>";
  704. html += "</span>";
  705. html += "</div>";
  706. html += "</div>"; //end of left
  707. html += '<div class="right">';
  708. html += '<div class="head_bar">';
  709. html += '<div class="title" >';
  710. html += '<div class="title_left" onclick="chapter_onclick(this)">';
  711. let sPaliTitle = chapter.title;
  712. if (chapter.title == "") {
  713. sPaliTitle = "unnamed";
  714. }
  715. if (
  716. typeof chapter.trans_title == "undefined" ||
  717. chapter.trans_title == ""
  718. ) {
  719. html += " <div class='title_1'>";
  720. switch (getCookie("language")) {
  721. case "my":
  722. html += roman_to_my(sPaliTitle);
  723. break;
  724. case "si":
  725. html += roman_to_si(sPaliTitle);
  726. break;
  727. default:
  728. html += sPaliTitle;
  729. break;
  730. }
  731. html += "</div>";
  732. } else {
  733. html += " <div class='title_1'>" + chapter.trans_title + "</div>";
  734. }
  735. html += '<div class="title_2" lang="pali">' + sPaliTitle + "</div>";
  736. html += '<div class="title_2" lang="pali">';
  737. //书名
  738. if (chapter.path) {
  739. let arrPath = false;
  740. if (Array.isArray(chapter.path)) {
  741. arrPath = chapter.path;
  742. } else {
  743. try {
  744. arrPath = JSON.parse(chapter.path);
  745. } catch (e) {
  746. console.error("json parse", chapter.path);
  747. }
  748. }
  749. if (arrPath && arrPath.length > 0) {
  750. html += "<span class='item'>";
  751. html +=
  752. "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  753. html +=
  754. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#journals'>";
  755. html += "</svg>";
  756. html += arrPath[0].title;
  757. html += "</span>";
  758. }
  759. }
  760. let chapterPara;
  761. if (chapter.paragraph) {
  762. }
  763. html += "</div>";
  764. html += "</div>";
  765. html += '<div class="title_right" >';
  766. html += "<span></span>";
  767. /*
  768. if(isSub){
  769. html += "<span></span>";
  770. }else{
  771. html += "<img class='chapter_dynamic_svg' src='/api/v2/progress-img/-chapter_dynamic-";
  772. html += chapter.book + "-";
  773. if(chapter.paragraph){
  774. html += chapter.paragraph;
  775. }else{
  776. html += chapter.para;
  777. }
  778. if(chapter.channel_id){
  779. html += "-ch_" + chapter.channel_id;
  780. }else{
  781. html += "-global";
  782. }
  783. html += "' />";
  784. }
  785. */
  786. html += "</div>";
  787. html += "</div>";
  788. html += '<div class="resource">';
  789. if (chapter.summary) {
  790. html += chapter.summary;
  791. }
  792. html += "</div>";
  793. html += '<div class="more_info">';
  794. //最下面一栏,左侧的标签列表
  795. html += "<div class='chapter_tag'>";
  796. if (chapter.tags) {
  797. html += renderChapterTags(chapter.tags);
  798. }
  799. html += "</div>";
  800. html += "<div class='palicanon_chapter_info'>";
  801. if (typeof chapter.type !== "undefined" && chapter.type === "article") {
  802. html += "<span class='item channel'>";
  803. html +=
  804. "<svg class='small_icon' style='width:16px;height:16px;fill: var(--box-bg-color1)'>";
  805. html +=
  806. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#person-circle'>";
  807. html += "</svg>";
  808. html +=
  809. "<span class='text' onclick=\"select_channel('" +
  810. chapter.channel_id +
  811. "')\">";
  812. html += chapter.channel_info.name;
  813. html += "</span>";
  814. html += "</span>";
  815. }
  816. if (chapter.created_at) {
  817. html += "<span class='item'>";
  818. html +=
  819. "<svg class='small_icon' style='width:16px;height:16px;fill: var(--box-bg-color1)'>";
  820. html +=
  821. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#clock'>";
  822. html += "</svg>";
  823. html += "<span class='text'>";
  824. html += getPassDataTime(new Date(chapter.created_at));
  825. html += "</span>";
  826. html += "</span>";
  827. }
  828. if (chapter.children && chapter.children.length > 0) {
  829. html += "<span class='item' onclick=\"subchapter_slideToggle(this)\">";
  830. html += "<span class='text'>";
  831. html += "展开折叠子章节 " + chapter.children.length;
  832. html += "</span>";
  833. html += "</span>";
  834. }
  835. html += "</div>";
  836. html += "</div>";
  837. html += "</div>"; //end of head bar
  838. html += "</div>";
  839. html += "</div>"; //end of main
  840. html += "<div class='subchapter'>";
  841. if (chapter.children) {
  842. html += "<ul class='subchapter_inner'>";
  843. for (const subchapter of chapter.children) {
  844. html += palicanon_render_chapter_row(subchapter, true);
  845. }
  846. html += "</ul>";
  847. }
  848. html += "</div>";
  849. html += "</li>";
  850. return html;
  851. }
  852. function subchapter_slideToggle(obj) {
  853. $(obj)
  854. .parent()
  855. .parent()
  856. .parent()
  857. .parent()
  858. .parent()
  859. .siblings(".subchapter")
  860. .slideToggle();
  861. }
  862. function tag_get_local_word(word) {
  863. let termKey = term_lookup_my(
  864. word,
  865. "",
  866. getCookie("userid"),
  867. getCookie("language")
  868. );
  869. if (typeof termKey == "undefined" || termKey === false || termKey === "") {
  870. switch (getCookie("language")) {
  871. case "my":
  872. return roman_to_my(word);
  873. case "si":
  874. return roman_to_si(word);
  875. default:
  876. return word;
  877. }
  878. } else {
  879. return termKey.meaning;
  880. }
  881. }
  882. function tag_render_others() {
  883. let strOthersTag = "";
  884. currTagLevel0 = new Array();
  885. $(".tag_others").html("");
  886. document.getElementById("main_tag").style.margin = 1 + "em";
  887. document.getElementById("main_tag").style.fontSize = 100 + "%";
  888. for (const key in allTags) {
  889. if (allTags.hasOwnProperty(key)) {
  890. let count = allTags[key];
  891. if ($("#tag_input").val().length > 0) {
  892. if (key.indexOf($("#tag_input").val()) >= 0) {
  893. strOthersTag =
  894. '<button class="canon-tag" onclick ="tag_click(\'' +
  895. key +
  896. "')\" >" +
  897. key +
  898. "(" +
  899. count +
  900. ")" +
  901. "</button>";
  902. }
  903. } else {
  904. let keyname = tag_get_local_word(key);
  905. strOthersTag =
  906. '<button class="canon-tag" title="' +
  907. key +
  908. '" onclick ="tag_click(\'' +
  909. key +
  910. "')\" >" +
  911. keyname +
  912. "(" +
  913. count +
  914. ")" +
  915. "</button>";
  916. }
  917. let thisLevel = 100;
  918. if (tag_level.hasOwnProperty(key)) {
  919. thisLevel = tag_level[key].level;
  920. if (tag_level[key].level == 0) {
  921. currTagLevel0[key] = 1;
  922. }
  923. }
  924. $(".tag_others[level='" + thisLevel + "']").html(
  925. $(".tag_others[level='" + thisLevel + "']").html() +
  926. strOthersTag
  927. );
  928. }
  929. }
  930. }
  931. function tag_click(tag) {
  932. list_tag.push(tag);
  933. render_selected_filter_list();
  934. tag_changed();
  935. }
  936. function tag_set(tag) {
  937. list_tag = new Array();
  938. if (Array.isArray(tag)) {
  939. for (const iterator of tag) {
  940. list_tag.push(iterator);
  941. }
  942. } else {
  943. list_tag.push(tag);
  944. }
  945. _tags = list_tag.join();
  946. render_selected_filter_list();
  947. tag_changed();
  948. }
  949. function renderChapterTags(tags) {
  950. let html = "";
  951. for (const iterator of tags) {
  952. html += "<tag onclick=\"tag_set('" + iterator.name + "')\">";
  953. html += "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  954. html +=
  955. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#tag'>";
  956. html += "</svg>";
  957. html +=
  958. '<span class="textt" title="' +
  959. iterator.name +
  960. '">' +
  961. tag_get_local_word(iterator.name) +
  962. "</span>";
  963. //html += '<span class="tag-delete" onclick ="tag_remove(\'' + iterator + "')\">✕</span>";
  964. html += "</tag>";
  965. }
  966. return html;
  967. }
  968. function render_selected_filter_list() {
  969. refresh_selected_tag();
  970. refresh_selected_channel();
  971. }
  972. function refresh_selected_tag() {
  973. let strListTag = "";
  974. for (const iterator of list_tag) {
  975. if (iterator != "") {
  976. strListTag += "<tag>";
  977. strListTag +=
  978. "<svg class='small_icon' style='fill: var(--box-bg-color1)'>";
  979. strListTag +=
  980. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#tag'>";
  981. strListTag += "</svg>";
  982. strListTag +=
  983. '<span class="textt" title="' +
  984. iterator +
  985. '">' +
  986. tag_get_local_word(iterator) +
  987. "</span>";
  988. strListTag +=
  989. '<span class="tag-delete" onclick ="tag_remove(\'' +
  990. iterator +
  991. "')\">✕</span>";
  992. strListTag += "</tag>";
  993. }
  994. }
  995. $("#tag_selected").html(strListTag);
  996. }
  997. function refresh_selected_channel() {
  998. let channels = _channel.split(",");
  999. let html = "";
  1000. for (const iterator of channels) {
  1001. if (_channelList) {
  1002. let item = _channelList.find(
  1003. (element) => element.channel_id == iterator
  1004. );
  1005. if (item) {
  1006. html += "<tag>";
  1007. html +=
  1008. '<span class="textt" title="">版本:' +
  1009. item.channel.name +
  1010. "</span>";
  1011. html +=
  1012. '<span class="tag-delete" onclick ="channel_tag_remove(\'' +
  1013. item.channel_id +
  1014. "')\">✕</span>";
  1015. html += "</tag>";
  1016. }
  1017. }
  1018. }
  1019. html += "</div>";
  1020. $("#channel_selected").html(html);
  1021. }
  1022. function channel_tag_remove(channelId) {
  1023. let channels = _channel.split(",");
  1024. if (channels.indexOf(channelId) >= 0) {
  1025. channels.splice(channels.indexOf(channelId), 1);
  1026. _channel = channels.join();
  1027. refresh_selected_channel();
  1028. tag_changed();
  1029. }
  1030. }
  1031. function tag_remove(tag) {
  1032. for (let i = 0; i < list_tag.length; i++) {
  1033. if (list_tag[i] == tag) {
  1034. list_tag.splice(i, 1);
  1035. }
  1036. }
  1037. render_selected_filter_list();
  1038. tag_changed();
  1039. }
  1040. function sortNumber(a, b) {
  1041. return b - a;
  1042. }
  1043. function tag_list_slide_toggle(element) {
  1044. if ($("#tag_list").css("display") == "none") {
  1045. $(element).addClass("active");
  1046. } else {
  1047. $(element).removeClass("active");
  1048. }
  1049. $("#tag_list").slideToggle();
  1050. }
  1051. function chapter_back(parent) {
  1052. if (_view == "category" && parent == 1) {
  1053. $("#index_div").removeClass("popup");
  1054. }
  1055. let curr = parseInt(parent) + 1;
  1056. let prt = parseInt(parent);
  1057. //隐藏当前的
  1058. for (let index = curr; index < 8; index++) {
  1059. $("#list_shell_" + index).removeClass();
  1060. $("#list_shell_" + index).addClass("hidden");
  1061. gBreadCrumbs[index - 1] = "";
  1062. }
  1063. //展开上一个
  1064. $("#list-" + prt).removeClass();
  1065. $("#list-" + prt).addClass("grid");
  1066. $("#list_shell_" + prt).removeClass();
  1067. $("#list_shell_" + prt).addClass("show");
  1068. RenderBreadCrumbs();
  1069. }
  1070. function categoryGoHome() {
  1071. updatePalicanonCategoryList();
  1072. $("#palicanon-category").show();
  1073. $("#chapter_shell").hide();
  1074. tag_set([]);
  1075. }
  1076. function updatePalicanonCategoryList(name = "__home__") {
  1077. switch (name) {
  1078. case "__home__":
  1079. _palicanonCategoryCurrent = _palicanonCategory.slice();
  1080. _palicanonCategoryPath = new Array();
  1081. _palicanonCategoryPath.push(_palicanonCategoryCurrent);
  1082. break;
  1083. case "__prev__":
  1084. _palicanonCategoryPath.pop();
  1085. _palicanonCategoryCurrent =
  1086. _palicanonCategoryPath[
  1087. _palicanonCategoryPath.length - 1
  1088. ].slice();
  1089. break;
  1090. default:
  1091. if (_palicanonCategoryCurrent.length > 0) {
  1092. let next = _palicanonCategoryCurrent.find(
  1093. (element) => element.name == name
  1094. );
  1095. if (typeof next !== "undefined") {
  1096. if (next.children && next.children.length > 0) {
  1097. //有子目录
  1098. _palicanonCategoryCurrent = next.children.slice();
  1099. _palicanonCategoryPath.push(
  1100. _palicanonCategoryCurrent.slice()
  1101. );
  1102. } else {
  1103. //没有子目录
  1104. tag_set(next.tag);
  1105. $("#palicanon-category").hide();
  1106. $("#chapter_shell").show();
  1107. }
  1108. }
  1109. } else {
  1110. }
  1111. break;
  1112. }
  1113. $("#palicanon-category").html(renderPalicanonCategoryList());
  1114. }
  1115. function renderPalicanonCategoryList() {
  1116. let html = "<ul class='chapter_list'>";
  1117. if (_palicanonCategoryPath.length > 1) {
  1118. html += "<li onclick=\"updatePalicanonCategoryList('__prev__')\">";
  1119. html += "上一级";
  1120. html += "</li>";
  1121. }
  1122. for (const item of _palicanonCategoryCurrent) {
  1123. html +=
  1124. "<li onclick=\"updatePalicanonCategoryList('" + item.name + "')\">";
  1125. html += "<div class='left_icon'>";
  1126. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1127. html +=
  1128. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#folder'>";
  1129. html += "</svg>";
  1130. html += "</div>";
  1131. html += "<div class='title'>";
  1132. html += '<div class="title_left" onclick="chapter_onclick(this)">';
  1133. html += '<div class="title_1">' + item.name + "</div>";
  1134. html += '<div class="title_2" lang="pali">' + item.name + "</div>";
  1135. html += "</div>";
  1136. html += '<div class="title_right">';
  1137. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1138. html +=
  1139. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-right'>";
  1140. html += "</svg>";
  1141. html += "</div>";
  1142. html += "</div>";
  1143. html += "</li>";
  1144. }
  1145. html += "</ul>";
  1146. return html;
  1147. }
  1148. function loadTagCategory(name = "default") {
  1149. $.getJSON("../palicanon/category/" + name + ".json", function (result) {
  1150. _palicanonCategory = result;
  1151. _palicanonCategoryCurrent = _palicanonCategory.slice();
  1152. _palicanonCategoryPath = new Array();
  1153. _palicanonCategoryPath.push(_palicanonCategoryCurrent.slice());
  1154. updatePalicanonCategoryList();
  1155. $("#tag-category").html("");
  1156. $("#tag-category").fancytree({
  1157. autoScroll: true,
  1158. selectMode: 1, // 1:single, 2:multi, 3:multi-hier
  1159. checkbox: false, // Show checkboxes.
  1160. source: tocGetTagCategory(result.slice()),
  1161. activate: function (e, data) {
  1162. console.log("tree", data);
  1163. tag_set(arrTagCategory[data.node.key]);
  1164. },
  1165. select: function (e, data) {
  1166. // Display list of selected nodes
  1167. currSelectNode = data.tree.getSelectedNodes();
  1168. },
  1169. });
  1170. });
  1171. }
  1172. var arrTagCategory = new Array();
  1173. function tocGetTagCategory(data) {
  1174. let output = new Array();
  1175. for (const iterator of data) {
  1176. let item = { key: com_uuid(), title: iterator.name, tag: iterator.tag };
  1177. arrTagCategory[item.key] = iterator.tag;
  1178. if (typeof iterator.children !== "undefined") {
  1179. item.children = tocGetTagCategory(iterator.children);
  1180. }
  1181. output.push(item);
  1182. }
  1183. return output;
  1184. }
  1185. function loadTagCategoryIndex() {
  1186. $.getJSON("../palicanon/category/index.json", function (result) {
  1187. let indexFilename = localStorage.getItem("palicanon_tag_category");
  1188. if (!indexFilename) {
  1189. indexFilename = "defualt";
  1190. }
  1191. let html = "";
  1192. for (const iterator of result) {
  1193. html += "<option ";
  1194. if (indexFilename == iterator.file) {
  1195. html += " selected ";
  1196. }
  1197. html +=
  1198. " value='" + iterator.file + "'>" + iterator.name + "</option>";
  1199. }
  1200. $("#tag_category_index").html(html);
  1201. });
  1202. }
  1203. function TagCategoryIndexchange(obj) {
  1204. localStorage.setItem("palicanon_tag_category", $(obj).val());
  1205. //loadTagCategory($(obj).val());
  1206. location.reload();
  1207. }
  1208. function RenderBreadCrumbs() {
  1209. let html = "";
  1210. html += "<span>";
  1211. html += '<a onclick="chapter_back(1)" title="' + gLocal.gui.close + '">';
  1212. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1213. html +=
  1214. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#arrow-left-square'>";
  1215. html += "</svg>";
  1216. html += "</a>";
  1217. html += "</span>";
  1218. for (const iterator of gBreadCrumbs) {
  1219. if (iterator.title1) {
  1220. html += "<span>";
  1221. html += "<svg class='icon' style='fill: var(--box-bg-color1)'>";
  1222. html +=
  1223. "<use xlink:href='../../node_modules/bootstrap-icons/bootstrap-icons.svg#chevron-right'>";
  1224. html += "</svg>";
  1225. html += "</span>";
  1226. html += "<span>";
  1227. html += '<a onclick="chapter_back(' + (iterator.level + 1) + ')">';
  1228. html += iterator.title1;
  1229. html += "</a>";
  1230. html += "</span>";
  1231. }
  1232. }
  1233. $("#bread-crumbs").html(html);
  1234. }
  1235. function select_channel(id, obj = null) {
  1236. _channel = id;
  1237. _nextPageStart = 0;
  1238. updataHistory();
  1239. communityGetChapter(_nextPageStart);
  1240. refresh_selected_channel();
  1241. console.log("change channel", _channel);
  1242. //$(obj).siblings.removeClass('active');
  1243. //$(obj).addClass('active');
  1244. }
  1245. function LoadAllChannel() {
  1246. $.getJSON(
  1247. "/api/v2/progress?view=channel",
  1248. {
  1249. lang: _lang,
  1250. channel_type: _channelType,
  1251. progress: _progress,
  1252. },
  1253. function (data, status) {
  1254. let html = "";
  1255. html += "<ul>";
  1256. _channelList = data.data.rows;
  1257. for (const iterator of data.data.rows) {
  1258. if (iterator.channel) {
  1259. html +=
  1260. "<li onclick=\"select_channel('" +
  1261. iterator.channel.uid +
  1262. "',this)\">";
  1263. html += iterator.channel.name + "(" + iterator.count + ")";
  1264. html += "</li>";
  1265. }
  1266. }
  1267. html += "</ul>";
  1268. $("#filter-author").html(html);
  1269. refresh_selected_channel();
  1270. }
  1271. );
  1272. }
  1273. function LoadAllLanguage() {
  1274. $.getJSON("/api/v2/progress?view=lang", {}, function (data, status) {
  1275. let html = "";
  1276. html += "<option value='auto'>自动选择语言</option>";
  1277. html += "<option value=''>全部语言</option>";
  1278. for (const iterator of data.data.rows) {
  1279. if (iterator.lang != "") {
  1280. html += "<option value='" + iterator.lang + "' ";
  1281. if (_langsetting == iterator.lang) {
  1282. html += " selected ";
  1283. }
  1284. html += ">";
  1285. html += iterator.lang + "(" + iterator.count + ")";
  1286. html += "</option>";
  1287. }
  1288. }
  1289. $("#setting_lang").html(html);
  1290. });
  1291. }
  1292. function ReanderMainMenu() {
  1293. let html = "";
  1294. html += "<span ";
  1295. if (_view == "community") {
  1296. html += "class='select'";
  1297. }
  1298. html +=
  1299. "><a href='index.php?view=community'>" +
  1300. gLocal.gui.community_new +
  1301. "</a></span>";
  1302. html += "<span ";
  1303. if (_view == "category") {
  1304. html += "class='select'";
  1305. }
  1306. html +=
  1307. "><a href='index.php?view=category' >" +
  1308. gLocal.gui.pali_text +
  1309. "</a></span>";
  1310. html += "<span ";
  1311. if (_view == "my") {
  1312. html += "class='select'";
  1313. }
  1314. html +=
  1315. "><a href='index.php?view=my' >" + gLocal.gui.my_read + "</a></span>";
  1316. $("#main_menu").html(html);
  1317. }
  1318. function loadContribution() {
  1319. $.getJSON("/api/v2/sent_history_contribution", function () {
  1320. console.log("success");
  1321. })
  1322. .done(function (data) {
  1323. let html = "";
  1324. html += "<ol>";
  1325. for (const item of data.data) {
  1326. html += "<li>";
  1327. html += item.username.nickname;
  1328. html += "—";
  1329. html += item.count;
  1330. html += "</li>";
  1331. }
  1332. html += "</ol>";
  1333. $("#contribution").find(".list").first().html(html);
  1334. })
  1335. .fail(function () {
  1336. console.log("error");
  1337. });
  1338. }