学堂在线 xuetangx.com 批量下载视频及字幕 Aria2脚本

1.提取视频和字幕的链接 2.按照上下文自动生成文件名 3.点击按钮通过 JSON-RPC 调用 aria2 下载至指定文件夹

  1. // ==UserScript==
  2. // @name 学堂在线 xuetangx.com 批量下载视频及字幕 Aria2脚本
  3. // @namespace mudan_cn
  4. // @version 2019.9.14
  5. // @description 1.提取视频和字幕的链接 2.按照上下文自动生成文件名 3.点击按钮通过 JSON-RPC 调用 aria2 下载至指定文件夹
  6. // @author mudan_cn
  7. // @match http://www.xuetangx.com/courses/**
  8. // @match https://www.xuetangx.com/courses/**
  9. // @license MIT License
  10. // @run-at document-idle
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // ==/UserScript==
  14.  
  15. $('div.course_mask').remove();
  16. class Aria2Config {
  17. }
  18. const default_aria2_config = {
  19. uri: 'http://localhost:6800/jsonrpc',
  20. token: '',
  21. storage_directory: 'D:\\\\'
  22. };
  23. let counter = 0;
  24. const id = setInterval(() => {
  25. try {
  26. const unit = $('.active.ui-accordion-header')[0].textContent.trim().replace(' ', ' ');
  27. const section = $('#accordion li.active p:first')[0].firstChild.textContent.trim().replace(' ', ' ');
  28. const videos = $('.xt_video_player').map((i, x) => x.getAttribute('src')).get();
  29. const transcripts = $('a[href$="transcript/download"]').map((i, x) => 'http://www.xuetangx.com' + x.getAttribute('href')).get();
  30. counter++;
  31. //loop and wait for the next turn
  32. if (videos.length < transcripts.length && counter < 10)
  33. return;
  34. //time out ,give up
  35. if (videos.length < transcripts.length && counter == 10) {
  36. clearInterval(id);
  37. console.error('视频地址加载失败');
  38. }
  39. clearInterval(id);
  40. console.log(`video ready, clear Interval\nvideos:${videos.length}\ntranscripts:${transcripts.length}`);
  41. console.log(videos);
  42. console.log(transcripts);
  43. //get_section_index
  44. const current_chapter = $('.chapter.is-open');
  45. const current_section = current_chapter.find('li.active');
  46. const section_index = ($('.chapter').index(current_chapter) + 1) + '.' + (current_section.parent().children().index(current_section) + 1);
  47. const video_title_node = $('#seq_content > div > div > div.vert.vert-0 > div > h2');
  48. //aria2 config settings
  49. let aria2_config = GM_getValue('aria2_config', default_aria2_config);
  50. console.log('current saved aria2_config:');
  51. console.log(aria2_config);
  52. $(`
  53. <div>
  54. <button id="configure_aria2_button" style="margin-bottom: 20px;">配置 aria2</button>
  55. <div id="configure_aria2_panel" style="display: none;margin: 0.5em;">
  56. uri: <input id="aria2_uri" value="${aria2_config.uri}"><br>
  57. token: <input id="aria2_token" value="${aria2_config.token}"><br>
  58. storage_directory: <input id="aria2_storage_directory" value="${aria2_config.storage_directory}"><br>
  59. <button id="save_aria2_settings_button" style="margin-bottom: 20px;">保存</button>
  60. </div>
  61. </div>
  62. `.replace(/ {4,}/g, '')).insertBefore(video_title_node);
  63. const configure_button = $('#configure_aria2_button');
  64. const configure_panel = $('#configure_aria2_panel');
  65. configure_button.on('click', () => {
  66. configure_panel.show();
  67. configure_button.css('color', 'black');
  68. });
  69. $('#save_aria2_settings_button').on('click', () => {
  70. aria2_config = {
  71. uri: $('#aria2_uri').val().toString(),
  72. token: $('#aria2_token').val().toString(),
  73. storage_directory: $('#aria2_storage_directory').val().toString()
  74. };
  75. GM_setValue('aria2_config', aria2_config);
  76. configure_button.css('color', 'green');
  77. configure_panel.hide();
  78. console.log('new aria2_config saved');
  79. console.log(aria2_config);
  80. });
  81. //build download buttons and actions
  82. videos.forEach((x, i) => {
  83. draw_buttons_and_links(x, get_file_name('mp4', videos.length > 1 ? (i + 1) : null), 'mp4');
  84. });
  85. transcripts.forEach((x, i) => {
  86. draw_buttons_and_links(x, get_file_name('srt', transcripts.length > 1 ? (i + 1) : null), 'srt');
  87. });
  88. function get_file_name(suffix, index) {
  89. return `${section_index} ${unit} ${section}${index ? ' ' + index : ''}.${suffix}`;
  90. }
  91. function draw_buttons_and_links(uri, file_name, suffix='') {
  92. $(` <div style="margin-top: 15px;margin-bottom: 15px;">
  93. <p style="margin-bottom: 0.3em;">${file_name}</p>
  94. <button class="BtnAria" style="margin-top: 10px;display: inline-block;">ARIA2 RPC</button>
  95. <button class="BtnBatchdown" style="margin-top: 10px;display: inline-block;">批量下载</button>
  96. <a href="${uri}" style="margin-top: 10px;display: inline-block;line-height: 55px;padding-left: 30px;" download="${file_name}">下载链接</a>
  97. </div>
  98. `.replace(/ {4,}/g, '')).on('click', 'button.BtnAria', (event) => {
  99. let success_button = event.target;
  100. console.log('success_button');
  101. send_aria2_download_rpc(uri, file_name, GM_getValue('aria2_config', default_aria2_config), (rpc_response) => {
  102. try {
  103. console.log('rpc sent successfully, server reply:');
  104. console.log(rpc_response);
  105. if (rpc_response.result) {
  106. success_button.style.color = 'green';
  107. }
  108. }
  109. catch (any) {
  110. console.error(rpc_response);
  111. }
  112. }, (json_rpc_sent, jqXHR, textStatus, errorThrown) => {
  113. console.error('error in send_aria2_download_rpc');
  114. console.log(aria2_config);
  115. console.log(json_rpc_sent);
  116. console.log(jqXHR);
  117. alert('aria2 rpc 发送失败,请检查console日志');
  118. });
  119. }).on('click', 'button.BtnBatchdown', (event)=>{
  120. if(!$('#win_batchdown').length){
  121. var chapters=$('div.chapter');
  122. $(`<div id="win_batchdown" style="background-color:white;position:fixed;z-index:99999;top:1%;left:30%;max-width:40%;max-height:87.7%;overflow:auto">
  123. <button onclick="$(this.parentNode).hide()">×</button> <button class="BtnBatchAria">发送到ARIA2</button>
  124. <button onclick="$(this.parentNode).find('input').prop('checked',true)" class=all>全选</button>
  125. <button onclick="$(this.parentNode).find('input').click()" class=reverse>反选</button><br>
  126. <input checked type=checkbox class=mp4>mp4 <input checked type=checkbox class=srt>srt<br>
  127. </div>`).appendTo($('body')).on('click', '.BtnBatchAria', function(eve){
  128. $('#win_batchdown').find('a').each(function(i,e){
  129. if(e.previousElementSibling.checked){
  130. e = $(e);
  131. $.get(e.attr('href'), function(res){
  132. $($(res).find('div.seq_contents').text()).find('div.video').each(function(i,d){
  133. d = $(d);
  134. if($('input.mp4').prop('checked'))
  135. $.getJSON('http://www.xuetangx.com/videoid2source/' + d.attr('data-ccsource'),function(json){
  136. send_aria2_download_rpc(json.sources.quality20[0],
  137. (e.text()+' '+i+d.siblings('h2').text()).replace(':',':')+'.mp4',
  138. GM_getValue('aria2_config', default_aria2_config),
  139. (res)=>{console.log(res)},(err)=>{console.error(err)});
  140. });
  141. if($('input.srt').prop('checked'))
  142. send_aria2_download_rpc('http://www.xuetangx.com'+d.find('li.video-tracks.video-download-button>a').attr('href'),
  143. (e.text()+' '+i+d.siblings('h2').text()).replace(':',':')+'.srt',
  144. GM_getValue('aria2_config', default_aria2_config),
  145. (res)=>{console.log(res)},(err)=>{console.error(err)});
  146. });
  147. },'html');
  148. }
  149. })
  150. });
  151. chapters.each(function(i, e){//每个章节
  152. var filename, iChapter = i+1, chname = $(e).find('h3>a').text();
  153. $(e).find('li>a').each(function(i, e){//每节课程
  154. var iLesson = i+1;
  155. e = $(e);
  156. filename = `${iChapter}.${iLesson} ${chname} ${e.find('p')[0].firstChild.textContent.trim()}`;
  157. $(`<input type=checkbox><a target=_blank href="${e.attr('href')}">${filename}</a><br/>`).appendTo($('#win_batchdown'));
  158. });
  159. });
  160. }
  161. else
  162. $('#win_batchdown').show();
  163. }).insertBefore(video_title_node);
  164. }
  165. }
  166. catch (any) {
  167. console.log(any);
  168. clearInterval(id);
  169. }
  170. }, 1000);
  171. //send json-rpc(with cookie) to aria2
  172. function send_aria2_download_rpc(uri, filename, aria2_config, success_callback, error_callback) {
  173. const json_rpc = {
  174. id: '',
  175. jsonrpc: '2.0',
  176. method: 'aria2.addUri',
  177. params: [
  178. `token:${aria2_config.token}`,
  179. [uri],
  180. {
  181. dir: aria2_config.storage_directory,
  182. out: filename,
  183. header: ['Cookie: ' + document.cookie]
  184. }
  185. ]
  186. };
  187. $.ajax({
  188. url: aria2_config.uri,
  189. //method:'POST' can only be used after jQuery 2.0
  190. type: 'POST',
  191. crossDomain: true,
  192. processData: false,
  193. data: JSON.stringify(json_rpc),
  194. contentType: 'application/json',
  195. success: success_callback,
  196. error: (jqXHR, textStatus, errorThrown) => {
  197. error_callback(json_rpc, jqXHR, textStatus, errorThrown);
  198. },
  199. });
  200. }
  201. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgudXNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxpQkFBaUI7QUFDakIsdUNBQXVDO0FBQ3ZDLGdEQUFnRDtBQUNoRCxnQ0FBZ0M7QUFDaEMsc0ZBQXNGO0FBQ3RGLG9CQUFvQjtBQUNwQixpQkFBaUI7QUFDakIsaUJBQWlCO0FBQ2pCLG1EQUFtRDtBQUNuRCxvREFBb0Q7QUFDcEQsOEZBQThGO0FBQzlGLDRCQUE0QjtBQUM1Qiw4QkFBOEI7QUFDOUIsNEJBQTRCO0FBQzVCLDRCQUE0QjtBQUM1QiwyRUFBMkU7QUFDM0Usa0JBQWtCO0FBQ2xCO0NBSUM7QUFFRCxNQUFNLG9CQUFvQixHQUFhO0lBQ25DLEdBQUcsRUFBQywrQkFBK0I7SUFDbkMsS0FBSyxFQUFDLEVBQUU7SUFDUixpQkFBaUIsRUFBQyxRQUFRO0NBQzdCLENBQUE7QUFJRCxJQUFJLE9BQU8sR0FBQyxDQUFDLENBQUE7QUFDYixNQUFNLEVBQUUsR0FBQyxXQUFXLENBQUM7SUFDakIsSUFBRyxDQUFDO1FBQ0EsTUFBTSxJQUFJLEdBQUMsQ0FBQyxDQUFDLDZCQUE2QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUMsR0FBRyxDQUFDLENBQUE7UUFDbEYsTUFBTSxPQUFPLEdBQUMsQ0FBQyxDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2pHLE1BQU0sTUFBTSxHQUFnQixDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxLQUFHLENBQUMsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FB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RCxDQUFDO0tBQ0osQ0FBQyxDQUFBO0FBQ0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vID09VXNlclNjcmlwdD09XG4vLyBAbmFtZSAgICAgICAgIOWtpuWgguWcqOe6vyDor77nqIvop4bpopHlj4rlrZfluZUgYXJpYTLkuIvovb3ohJrmnKxcbi8vIEBuYW1lc3BhY2UgICAgaHR0cHM6Ly9naXRodWIuY29tL1NoZW5Ib25nRmVpL1xuLy8gQHZlcnNpb24gICAgICAyMDE3LjguMjcuMTkuMTBcbi8vIEBkZXNjcmlwdGlvbiAgMS7mj5Dlj5bop4bpopHlkozlrZfluZXnmoTpk77mjqU8YnI+Mi7mjInnhafkuIrkuIvmlofoh6rliqjnlJ/miJDmlofku7blkI08YnI+My7ngrnlh7vmjInpkq7pgJrov4cgSk9TTi1SUEMg6LCD55SoIGFyaWEyIOS4i+i9veiHs+aMh+WumuaWh+S7tuWkuVxuLy8gQGF1dGhvciAgICAgICDmsojpuL/po55cbi8vIEBob21lcGFnZVVSTCAgXG4vLyBAdXBkYXRlVVJMICAgIFxuLy8gQG1hdGNoICAgICAgICBodHRwOi8vd3d3Lnh1ZXRhbmd4LmNvbS9jb3Vyc2VzLyoqXG4vLyBAbWF0Y2ggICAgICAgIGh0dHBzOi8vd3d3Lnh1ZXRhbmd4LmNvbS9jb3Vyc2VzLyoqXG4vLyBAaWNvbiAgICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9TaGVuSG9uZ0ZlaS94dWV0YW5neC1hcmlhMi1kb3dubG9hZC11c2Vyc2NyaXB0L2Zhdmljb24ucG5nXG4vLyBAbGljZW5zZSAgICAgIE1JVCBMaWNlbnNlXG4vLyBAcnVuLWF0ICAgICAgIGRvY3VtZW50LWlkbGVcbi8vIEBncmFudCAgICAgICAgR01fZ2V0VmFsdWVcbi8vIEBncmFudCAgICAgICAgR01fc2V0VmFsdWVcbi8vIEBfcmVxdWlyZSAgICAgIGZpbGU6Ly9FOlxcU0RLXFx4dWV0YW5neC1hcmlhMi1kb3dubG9hZC11c2Vyc2NyaXB0XFxpbmRleC5qc1xuLy8gPT0vVXNlclNjcmlwdD09XG5jbGFzcyBBcmlhMkNvbmZpZ3tcbiAgICB1cmk6c3RyaW5nXG4gICAgdG9rZW46c3RyaW5nXG4gICAgc3RvcmFnZV9kaXJlY3Rvcnk6c3RyaW5nXG59XG5cbmNvbnN0IGRlZmF1bHRfYXJpYTJfY29uZmlnOkFyaWEyQ29uZmlnPXtcbiAgICB1cmk6J2h0dHA6Ly9sb2NhbGhvc3Q6NjgwMC9qc29ucnBjJyxcbiAgICB0b2tlbjonJyxcbiAgICBzdG9yYWdlX2RpcmVjdG9yeTonRDpcXFxcXFxcXCdcbn1cbmRlY2xhcmUgZnVuY3Rpb24gR01fZ2V0VmFsdWUobmFtZTpzdHJpbmcsZGVmYXVsdFZhbHVlOmFueSk6YW55XG5kZWNsYXJlIGZ1bmN0aW9uIEdNX3NldFZhbHVlKG5hbWU6c3RyaW5nLHZhbHVlOmFueSk6YW55XG5cbmxldCBjb3VudGVyPTBcbmNvbnN0IGlkPXNldEludGVydmFsKCgpPT57XG4gICAgdHJ5e1xuICAgICAgICBjb25zdCB1bml0PSQoJy5hY3RpdmUudWktYWNjb3JkaW9uLWhlYWRlcicpWzBdLnRleHRDb250ZW50LnRyaW0oKS5yZXBsYWNlKCfCoCcsJyAnKVxuICAgICAgICBjb25zdCBzZWN0aW9uPSQoJyNhY2NvcmRpb24gbGkuYWN0aXZlIHA6Zmlyc3QnKVswXS5maXJzdENoaWxkLnRleHRDb250ZW50LnRyaW0oKS5yZXBsYWNlKCfCoCcsJyAnKVxuICAgICAgICBjb25zdCB2aWRlb3M9PHN0cmluZ1tdPjxhbnk+JCgnLnh0X3ZpZGVvX3BsYXllcicpLm1hcCgoaSx4KT0+eC5nZXRBdHRyaWJ1dGUoJ3NyYycpKS5nZXQoKVxuICAgICAgICBjb25zdCB0cmFuc2NyaXB0cz08c3RyaW5nW10+PGFueT4kKCdhW2hyZWYkPVwidHJhbnNjcmlwdC9kb3dubG9hZFwiXScpLm1hcCgoaSx4KT0+J2h0dHA6Ly93d3cueHVldGFuZ3guY29tJyt4LmdldEF0dHJpYnV0ZSgnaHJlZicpKS5nZXQoKVxuICAgICAgICBcbiAgICAgICAgY291bnRlcisrXG4gICAgICAgIC8vbG9vcCBhbmQgd2FpdCBmb3IgdGhlIG5leHQgdHVyblxuICAgICAgICBpZih2aWRlb3MubGVuZ3RoPHRyYW5zY3JpcHRzLmxlbmd0aCYmY291bnRlcjwxMCkgcmV0dXJuXG4gICAgICAgIC8vdGltZSBvdXQgLGdpdmUgdXBcbiAgICAgICAgaWYodmlkZW9zLmxlbmd0aDx0cmFuc2NyaXB0cy5sZW5ndGgmJmNvdW50ZXI9PTEwKXtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaWQpXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCfop4bpopHlnLDlnYDliqDovb3lpLHotKUnKVxuICAgICAgICB9XG4gICAgICAgIGNsZWFySW50ZXJ2YWwoaWQpXG4gICAgICAgIGNvbnNvbGUubG9nKGB2aWRlbyByZWFkeSwgY2xlYXIgSW50ZXJ2YWxcXG52aWRlb3M6JHt2aWRlb3MubGVuZ3RofVxcbnRyYW5zY3JpcHRzOiR7dHJhbnNjcmlwdHMubGVuZ3RofWApXG4gICAgICAgIGNvbnNvbGUubG9nKHZpZGVvcylcbiAgICAgICAgY29uc29sZS5sb2codHJhbnNjcmlwdHMpXG4gICAgICAgIC8vZ2V0X3NlY3Rpb25faW5kZXhcbiAgICAgICAgY29uc3QgY3VycmVudF9jaGFwdGVyPSQoJy5jaGFwdGVyLmlzLW9wZW4nKVxuICAgICAgICBjb25zdCBjdXJyZW50X3NlY3Rpb249Y3VycmVudF9jaGFwdGVyLmZpbmQoJ2xpLmFjdGl2ZScpXG4gICAgICAgIGNvbnN0IHNlY3Rpb25faW5kZXg6c3RyaW5nPSgkKCcuY2hhcHRlcicpLmluZGV4KGN1cnJlbnRfY2hhcHRlcikrMSkrJy4nKyhjdXJyZW50X3NlY3Rpb24ucGFyZW50KCkuY2hpbGRyZW4oKS5pbmRleChjdXJyZW50X3NlY3Rpb24pKzEpXG4gICAgICAgIFxuICAgICAgICBjb25zdCB2aWRlb190aXRsZV9ub2RlPSQoJyNzZXFfY29udGVudCA+IGRpdiA+IGRpdiA+IGRpdi52ZXJ0LnZlcnQtMCA+IGRpdiA+IGgyJylcbiAgICAgICAgXG4gICAgICAgIC8vYXJpYTIgY29uZmlnIHNldHRpbmdzXG4gICAgICAgIGxldCBhcmlhMl9jb25maWc6QXJpYTJDb25maWc9R01fZ2V0VmFsdWUoJ2FyaWEyX2NvbmZpZycsZGVmYXVsdF9hcmlhMl9jb25maWcpXG4gICAgICAgIGNvbnNvbGUubG9nKCdjdXJyZW50IHNhdmVkIGFyaWEyX2NvbmZpZzonKVxuICAgICAgICBjb25zb2xlLmxvZyhhcmlhMl9jb25maWcpXG4gICAgICAgICQoYFxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGlkPVwiY29uZmlndXJlX2FyaWEyX2J1dHRvblwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMjBweDtcIj7phY3nva4gYXJpYTI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVwiY29uZmlndXJlX2FyaWEyX3BhbmVsXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO21hcmdpbjogMC41ZW07XCI+XG4gICAgICAgICAgICAgICAgICAgIHVyaTogPGlucHV0IGlkPVwiYXJpYTJfdXJpXCIgdmFsdWU9XCIke2FyaWEyX2NvbmZpZy51cml9XCI+PGJyPlxuICAgICAgICAgICAgICAgICAgICB0b2tlbjogPGlucHV0IGlkPVwiYXJpYTJfdG9rZW5cIiB2YWx1ZT1cIiR7YXJpYTJfY29uZmlnLnRva2VufVwiPjxicj5cbiAgICAgICAgICAgICAgICAgICAgc3RvcmFnZV9kaXJlY3Rvcnk6IDxpbnB1dCBpZD1cImFyaWEyX3N0b3JhZ2VfZGlyZWN0b3J5XCIgdmFsdWU9XCIke2FyaWEyX2NvbmZpZy5zdG9yYWdlX2RpcmVjdG9yeX1cIj48YnI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gaWQ9XCJzYXZlX2FyaWEyX3NldHRpbmdzX2J1dHRvblwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMjBweDtcIj7kv53lrZg8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICBgLnJlcGxhY2UoLyB7NCx9L2csJycpXG4gICAgICAgICkuaW5zZXJ0QmVmb3JlKHZpZGVvX3RpdGxlX25vZGUpXG4gICAgICAgIGNvbnN0IGNvbmZpZ3VyZV9idXR0b249JCgnI2NvbmZpZ3VyZV9hcmlhMl9idXR0b24nKVxuICAgICAgICBjb25zdCBjb25maWd1cmVfcGFuZWw9JCgnI2NvbmZpZ3VyZV9hcmlhMl9wYW5lbCcpXG4gICAgICAgIGNvbmZpZ3VyZV9idXR0b24ub24oJ2NsaWNrJywoKT0+e1xuICAgICAgICAgICAgY29uZmlndXJlX3BhbmVsLnNob3coKVxuICAgICAgICAgICAgY29uZmlndXJlX2J1dHRvbi5jc3MoJ2NvbG9yJywnYmxhY2snKVxuICAgICAgICB9KVxuICAgICAgICAkKCcjc2F2ZV9hcmlhMl9zZXR0aW5nc19idXR0b24nKS5vbignY2xpY2snLCgpPT57XG4gICAgICAgICAgICBhcmlhMl9jb25maWc9e1xuICAgICAgICAgICAgICAgIHVyaTokKCcjYXJpYTJfdXJpJykudmFsKCkudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICB0b2tlbjokKCcjYXJpYTJfdG9rZW4nKS52YWwoKS50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIHN0b3JhZ2VfZGlyZWN0b3J5OiQoJyNhcmlhMl9zdG9yYWdlX2RpcmVjdG9yeScpLnZhbCgpLnRvU3RyaW5nKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEdNX3NldFZhbHVlKCdhcmlhMl9jb25maWcnLGFyaWEyX2NvbmZpZylcbiAgICAgICAgICAgIGNvbmZpZ3VyZV9idXR0b24uY3NzKCdjb2xvcicsJ2dyZWVuJylcbiAgICAgICAgICAgIGNvbmZpZ3VyZV9wYW5lbC5oaWRlKClcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCduZXcgYXJpYTJfY29uZmlnIHNhdmVkJylcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGFyaWEyX2NvbmZpZylcbiAgICAgICAgfSlcbiAgICAgICAgLy9idWlsZCBkb3dubG9hZCBidXR0b25zIGFuZCBhY3Rpb25zXG4gICAgICAgIHZpZGVvcy5mb3JFYWNoKCh4LGkpPT57XG4gICAgICAgICAgICBkcmF3X2J1dHRvbnNfYW5kX2xpbmtzKHgsZ2V0X2ZpbGVfbmFtZSgnbXA0Jyx2aWRlb3MubGVuZ3RoPjE/KGkrMSk6bnVsbCkpXG4gICAgICAgIH0pXG4gICAgICAgIHRyYW5zY3JpcHRzLmZvckVhY2goKHgsaSk9PntcbiAgICAgICAgICAgIGRyYXdfYnV0dG9uc19hbmRfbGlua3MoeCxnZXRfZmlsZV9uYW1lKCdzcnQnLHRyYW5zY3JpcHRzLmxlbmd0aD4xPyhpKzEpOm51bGwpKVxuICAgICAgICB9KVxuICAgICAgICBcbiAgICAgICAgZnVuY3Rpb24gZ2V0X2ZpbGVfbmFtZShzdWZmaXg6c3RyaW5nLGluZGV4PzpudW1iZXIpe1xuICAgICAgICAgICAgcmV0dXJuIGAke3NlY3Rpb25faW5kZXh9ICR7dW5pdH0gJHtzZWN0aW9ufSR7aW5kZXg/JyAnK2luZGV4OicnfS4ke3N1ZmZpeH1gXG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZHJhd19idXR0b25zX2FuZF9saW5rcyh1cmk6c3RyaW5nLGZpbGVfbmFtZTpzdHJpbmcpOnZvaWR7XG4gICAgICAgICAgICAkKGBcbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMTVweDttYXJnaW4tYm90dG9tOiAxNXB4O1wiPlxuICAgICAgICAgICAgICAgICAgICA8cCBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDAuM2VtO1wiPiR7ZmlsZV9uYW1lfTwvcD5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBzdHlsZT1cIm1hcmdpbi10b3A6IDEwcHg7ZGlzcGxheTogaW5saW5lLWJsb2NrO1wiPkFSSUEyIFJQQzwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiJHt1cml9XCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMHB4O2Rpc3BsYXk6IGlubGluZS1ibG9jaztsaW5lLWhlaWdodDogNTVweDtwYWRkaW5nLWxlZnQ6IDMwcHg7XCIgZG93bmxvYWQ9XCIke2ZpbGVfbmFtZX1cIj7kuIvovb3pk77mjqU8L2E+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgLnJlcGxhY2UoLyB7NCx9L2csJycpKVxuICAgICAgICAgICAgLm9uKCdjbGljaycsJ2J1dHRvbicsKGV2ZW50KT0+e1xuICAgICAgICAgICAgICAgIGxldCBzdWNjZXNzX2J1dHRvbj1ldmVudC50YXJnZXRcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc3VjY2Vzc19idXR0b24nKVxuICAgICAgICAgICAgICAgIHNlbmRfYXJpYTJfZG93bmxvYWRfcnBjKFxuICAgICAgICAgICAgICAgICAgICB1cmksXG4gICAgICAgICAgICAgICAgICAgIGZpbGVfbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgR01fZ2V0VmFsdWUoJ2FyaWEyX2NvbmZpZycsZGVmYXVsdF9hcmlhMl9jb25maWcpLFxuICAgICAgICAgICAgICAgICAgICAocnBjX3Jlc3BvbnNlKT0+e1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdycGMgc2VudCBzdWNjZXNzZnVsbHksIHNlcnZlciByZXBseTonKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJwY19yZXNwb25zZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihycGNfcmVzcG9uc2UucmVzdWx0KXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc19idXR0b24uc3R5bGUuY29sb3I9J2dyZWVuJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1jYXRjaChhbnkpe2NvbnNvbGUuZXJyb3IocnBjX3Jlc3BvbnNlKX1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGpzb25fcnBjX3NlbnQsanFYSFI6SlF1ZXJ5WEhSLHRleHRTdGF0dXM6c3RyaW5nLGVycm9yVGhyb3duOnN0cmluZyk9PntcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ2Vycm9yIGluIHNlbmRfYXJpYTJfZG93bmxvYWRfcnBjJylcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGFyaWEyX2NvbmZpZylcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGpzb25fcnBjX3NlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhqcVhIUilcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KCdhcmlhMiBycGMg5Y+R6YCB5aSx6LSl77yM6K+35qOA5p+lY29uc29sZeaXpeW/lycpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmluc2VydEJlZm9yZSh2aWRlb190aXRsZV9ub2RlKVxuICAgICAgICB9XG4gICAgfWNhdGNoKGFueSl7XG4gICAgICAgIGNvbnNvbGUubG9nKGFueSlcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpZClcbiAgICB9XG59LDEwMDApXG5cbi8vc2VuZCBqc29uLXJwYyh3aXRoIGNvb2tpZSkgdG8gYXJpYTJcbmZ1bmN0aW9uIHNlbmRfYXJpYTJfZG93bmxvYWRfcnBjKFxuICAgIHVyaTpzdHJpbmcsXG4gICAgZmlsZW5hbWU6c3RyaW5nLFxuICAgIGFyaWEyX2NvbmZpZzpBcmlhMkNvbmZpZyxcbiAgICBzdWNjZXNzX2NhbGxiYWNrPzoocnBjX3Jlc3BvbnNlOmFueSk9PnZvaWQsXG4gICAgZXJyb3JfY2FsbGJhY2s/Oihqc29uX3JwY19zZW50Om9iamVjdCxqcVhIUjpKUXVlcnlYSFIsdGV4dFN0YXR1czpzdHJpbmcsZXJyb3JUaHJvd246c3RyaW5nKT0+dm9pZFxuKXtcbiAgICBjb25zdCBqc29uX3JwYz17XG4gICAgICAgIGlkOicnLFxuICAgICAgICBqc29ucnBjOicyLjAnLFxuICAgICAgICBtZXRob2Q6J2FyaWEyLmFkZFVyaScsXG4gICAgICAgIHBhcmFtczpbXG4gICAgICAgICAgICBgdG9rZW46JHthcmlhMl9jb25maWcudG9rZW59YCxcbiAgICAgICAgICAgIFt1cmldLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGRpcjphcmlhMl9jb25maWcuc3RvcmFnZV9kaXJlY3RvcnksXG4gICAgICAgICAgICAgICAgb3V0OmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIGhlYWRlcjpbJ0Nvb2tpZTogJytkb2N1bWVudC5jb29raWVdXG4gICAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICB9XG4gICAgJC5hamF4KHtcbiAgICB1cmw6YXJpYTJfY29uZmlnLnVyaSxcbiAgICAvL21ldGhvZDonUE9TVCcgY2FuIG9ubHkgYmUgdXNlZCBhZnRlciBqUXVlcnkgMi4wXG4gICAgdHlwZTonUE9TVCcsXG4gICAgY3Jvc3NEb21haW46dHJ1ZSxcbiAgICBwcm9jZXNzRGF0YTpmYWxzZSxcbiAgICBkYXRhOkpTT04uc3RyaW5naWZ5KGpzb25fcnBjKSxcbiAgICBjb250ZW50VHlwZTonYXBwbGljYXRpb24vanNvbicsXG4gICAgc3VjY2VzczpzdWNjZXNzX2NhbGxiYWNrLFxuICAgIGVycm9yOihqcVhIUjpKUXVlcnlYSFIsdGV4dFN0YXR1czpzdHJpbmcsZXJyb3JUaHJvd246c3RyaW5nKT0+e1xuICAgICAgICBlcnJvcl9jYWxsYmFjayhqc29uX3JwYyxqcVhIUix0ZXh0U3RhdHVzLGVycm9yVGhyb3duKVxuICAgIH0sXG59KVxufSJdfQ==

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址