Biliplus Evolved

简单的B+增强脚本

目前為 2024-01-26 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Biliplus Evolved
  3. // @version 0.10.7.2
  4. // @description 简单的B+增强脚本
  5. // @author DeltaFlyer
  6. // @copyright 2023, DeltaFlyer(https://github.com/DeltaFlyerW)
  7. // @license MIT
  8. // @match https://*.biliplus.com/*
  9. // @run-at document-end
  10. // @grant unsafeWindow
  11. // @grant GM_xmlhttpRequest
  12. // @grant GM_setValue
  13. // @grant GM_getValue
  14. // @connect api.bilibili.com
  15. // @connect comment.bilibili.com
  16. // @connect delflare505.win
  17. // @icon https://www.biliplus.com/favicon.ico
  18. // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.9.1/jszip.min.js
  19. // @namespace https://greasyfork.org/users/927887
  20. // ==/UserScript==
  21.  
  22.  
  23. (function () {
  24.  
  25. 'use strict';
  26. let toastText = (function () {
  27. let html = `
  28. <style>
  29. .df-bubble-container {
  30. position: fixed;
  31. bottom: 20px;
  32. right: 20px;
  33. z-index: 1000;
  34. display: block !important;
  35. }
  36.  
  37. .df-bubble {
  38. background-color: #333;
  39. color: white;
  40. padding: 10px 20px;
  41. border-radius: 5px;
  42. margin-bottom: 10px;
  43. opacity: 0;
  44. transition: opacity 0.5s ease-in-out;
  45. max-width: 300px;
  46. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2);
  47. display: block !important;
  48. }
  49.  
  50. .df-show-bubble {
  51. opacity: 1;
  52. }
  53. </style>
  54. <div class="df-bubble-container" id="bubbleContainer"></div>`
  55. document.body.insertAdjacentHTML("beforeend", html)
  56. let bubbleContainer = document.querySelector('.df-bubble-container')
  57.  
  58. function createToast(text) {
  59. console.log('toast', text)
  60. const bubble = document.createElement('div');
  61. bubble.classList.add('df-bubble');
  62. bubble.textContent = text;
  63.  
  64. bubbleContainer.appendChild(bubble);
  65. setTimeout(() => {
  66. bubble.classList.add('df-show-bubble');
  67. setTimeout(() => {
  68. bubble.classList.remove('df-show-bubble');
  69. setTimeout(() => {
  70. bubbleContainer.removeChild(bubble);
  71. }, 500); // Remove the bubble after fade out
  72. }, 3000); // Show bubble for 3 seconds
  73. }, 100); // Delay before showing the bubble
  74. }
  75.  
  76. return createToast
  77. })();
  78.  
  79. async function sleep(time) {
  80. await new Promise((resolve) => setTimeout(resolve, time));
  81. }
  82.  
  83.  
  84. async function xhrGet(url) {
  85. function isCors(url) {
  86. if (url[0] === '/') return false
  87. // Extract the domain from the URL
  88. const urlDomain = new URL(url).hostname;
  89.  
  90. // Extract the domain from the current page's URL
  91. const currentDomain = window.location.hostname;
  92.  
  93. // Check if the domains are different (CORS request)
  94. return urlDomain !== currentDomain;
  95. }
  96.  
  97. console.log('Get', url);
  98. if (isCors(url)) {
  99. // Use GM_xmlhttpRequest for cross-origin requests
  100. return new Promise((resolve) => {
  101. GM_xmlhttpRequest({
  102. method: 'GET',
  103. url: url,
  104. withCredentials: true,
  105. onload: (response) => {
  106. if (response.status === 200) {
  107. resolve(response.responseText);
  108. } else {
  109. resolve(null);
  110. }
  111. },
  112. onerror: (error) => {
  113. console.error('GM_xmlhttpRequest error:', error);
  114. resolve(null);
  115. },
  116. });
  117. });
  118. } else {
  119. // Use XMLHttpRequest for same-origin requests
  120. return new Promise((resolve) => {
  121. const xhr = new XMLHttpRequest();
  122. xhr.open('GET', url, true);
  123. xhr.withCredentials = true;
  124.  
  125. xhr.send();
  126.  
  127. xhr.onreadystatechange = async () => {
  128. if (xhr.readyState === 4) {
  129. if (xhr.status === 200) {
  130. resolve(xhr.responseText);
  131. } else {
  132. resolve(null);
  133. }
  134. }
  135. };
  136. });
  137. }
  138. }
  139.  
  140. function downloadFile(fileName, content, type = 'text/plain;charset=utf-8') {
  141. let aLink = document.createElement('a');
  142. let blob
  143. if (typeof (content) == 'string')
  144. blob = new Blob([content], {'type': type})
  145. else blob = content
  146. aLink.download = fileName;
  147. let url = URL.createObjectURL(blob)
  148. aLink.href = url
  149. aLink.click()
  150. URL.revokeObjectURL(url)
  151. }
  152.  
  153. function bv2av(str) {
  154. const table = [...'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'];
  155. const s = [11, 10, 3, 8, 4, 6];
  156. const xor = 177451812;
  157. const add = 8728348608;
  158. let result = 0;
  159. let i = 0;
  160. while (i < 6) {
  161. result += table.indexOf(str[s[i]]) * 58 ** i;
  162. i += 1;
  163. }
  164. return result - add ^ xor
  165. }
  166.  
  167. async function aidQuery() {
  168. function transform(src) {
  169. let dst = {}
  170. dst.id = src.id
  171. dst.ver = 1
  172. dst.aid = src.id
  173. dst.lastupdatets = Math.floor(new Date().getTime() / 1000)
  174. dst.lastupdate = new Date().toLocaleString();
  175. if (src.title === "已失效视频") {
  176. dst.title = document.title.slice(0, document.title.indexOf(" - "))
  177. dst.pic = document.querySelector('.detail_cover').src
  178. } else {
  179. dst.pic = src.cover
  180. dst.title = src.title
  181. }
  182. dst.description = src.intro
  183.  
  184. dst.tid = src.tid
  185. dst.typename = "tid_" + src.tid
  186. dst.created = src.pubtime
  187. dst.created_at = new Date(src.pubtime * 1000).toLocaleString()
  188. dst.author = src.upper.name
  189. dst.mid = src.upper.mid
  190. dst.play = src.cnt_info.play.toString()
  191. dst.coins = src.cnt_info.coin
  192. dst.review = src.cnt_info.reply
  193. dst.video_review = src.cnt_info.danmaku
  194. dst.favorites = src.cnt_info.collect
  195. dst.tag = "tag_undefined"
  196. let list = []
  197. for (let page of src.pages) {
  198. list.push({
  199. "page": page.page,
  200. "type": page.from,
  201. "cid": page.id,
  202. "vid": undefined,
  203. "part": page.title + "_时长" + page.duration + "秒",
  204. "duration": page.duration
  205. })
  206. }
  207. dst.list = list
  208. return dst
  209. }
  210.  
  211. let aid
  212. let href = new URL(window.location.href)
  213. if (href.searchParams.has("get_info")) {
  214. aid = unsafeWindow.av
  215. href.searchParams.delete("get_info")
  216. history.pushState(null, document.title, href.toString());
  217. } else {
  218. aid = window.prompt("请输入要查询的aid或bvid", unsafeWindow.av)
  219. if (!/^\d+$/.exec(aid)) {
  220. if (/^BV/.exec(aid)) {
  221. aid = bv2av(aid)
  222. } else {
  223. alert("请输入正确的视频号,bv号请以BV开头")
  224. return
  225. }
  226. }
  227. if (Number(aid) !== unsafeWindow.av) {
  228. href.searchParams.set("get_info", '1')
  229. window.location.href = href.toString()
  230. }
  231. }
  232. let url = `https://delflare505.win/getVideoInfo?aid=` + aid
  233.  
  234. let response = await xhrGet(url)
  235. let body = JSON.parse(await response)
  236.  
  237. let videoInfo = transform(body.data)
  238. unsafeWindow.videoInfo = videoInfo
  239. if (unsafeWindow.cloudmoe) {
  240. let cacheInfo = JSON.parse(JSON.stringify(videoInfo))
  241. cacheInfo.isDetailed = true
  242. cacheInfo.keywords = ""
  243. cacheInfo = {
  244. code: 0,
  245. data: {
  246. id: cacheInfo.id,
  247. info: cacheInfo,
  248. parts: cacheInfo.list,
  249. },
  250. }
  251. unsafeWindow.cloudmoe(cacheInfo)
  252. } else {
  253. unsafeWindow.view(videoInfo)
  254. }
  255. }
  256.  
  257. sleep(200).then(() => {
  258. if (new URL(window.location.href).searchParams.has("get_info")) {
  259. aidQuery(unsafeWindow.av)
  260. }
  261. })
  262.  
  263.  
  264. class CustomEventEmitter {
  265. constructor() {
  266. this.eventListeners = {};
  267. }
  268.  
  269. addEventListener(event, callback) {
  270. if (!this.eventListeners[event]) {
  271. this.eventListeners[event] = [];
  272. }
  273. this.eventListeners[event].push(callback);
  274. }
  275.  
  276. removeEventListener(event, callback) {
  277. if (this.eventListeners[event]) {
  278. const index = this.eventListeners[event].indexOf(callback);
  279. if (index !== -1) {
  280. this.eventListeners[event].splice(index, 1);
  281. }
  282. }
  283. }
  284.  
  285. postMessage(data) {
  286. const event = 'message'
  287. console.log(data)
  288. if (this.eventListeners[event]) {
  289. this.eventListeners[event].forEach(callback => {
  290. callback({data: data});
  291. });
  292. }
  293. }
  294. }
  295.  
  296. class ObjectRegistry {
  297. constructor() {
  298. this.registeredObjects = new Set();
  299. }
  300.  
  301. register(obj) {
  302. if (this.registeredObjects.has(obj)) {
  303. throw new Error('Object is already registered.');
  304. }
  305. this.registeredObjects.add(obj);
  306. }
  307. }
  308.  
  309. const broadcastChannel = new CustomEventEmitter()
  310.  
  311. function validateTitle(title) {
  312. return title.replace(/[\/\\\:\*\?\"\<\>\|]/g, '_')
  313. }
  314.  
  315. function panel() {
  316. function getLocalSetting(key) {
  317. let value = GM_getValue(key)
  318. console.log('get', key, value)
  319. if (value) {
  320.  
  321. return value
  322. } else {
  323. return {}
  324. }
  325. }
  326.  
  327. function setDefaultValue(currentSetting, settingPanelOptions) {
  328. for (let option of settingPanelOptions) {
  329. if (option.id) {
  330. if (!currentSetting[option.id]) {
  331. currentSetting[option.id] = option.default
  332. }
  333. } else if (option.children) {
  334. for (let child of option.children) {
  335. if (child.id) {
  336. if (!currentSetting[child.id]) {
  337. currentSetting[child.id] = child.default
  338. }
  339. }
  340. }
  341. }
  342. }
  343. }
  344.  
  345. function saveLocalSetting(key, value) {
  346. console.log('save', key, value)
  347. GM_setValue(key, value)
  348. }
  349.  
  350. let settingPanelOptions = [
  351. {type: 'section', 'label': '抓取时段:'},
  352. {
  353. type: 'row', children: [
  354. {
  355. 'type': 'numberInput',
  356. 'id': 'capturePeriodStart',
  357. label: "从视频发布起第",
  358. default: 0,
  359. suffixLabel: '天开始, ',
  360. splitter: ' '
  361. },
  362. {
  363. 'type': 'numberInput',
  364. 'id': 'capturePeriodEnd',
  365. label: "至第",
  366. default: -1,
  367. suffixLabel: '天结束',
  368. splitter: ' '
  369. },
  370. ]
  371. },
  372. {type: 'sectionEnd'},
  373. {
  374. type: 'row', children: [
  375. {type: 'checkbox', id: 'splitFileByTime', label: '按时间段分割弹幕文件'}
  376. ]
  377. },
  378. ]
  379.  
  380. let currentSetting = getLocalSetting("danmakuSetting")
  381. setDefaultValue(currentSetting, settingPanelOptions)
  382. let showSettingPanel = (function (settingPanelOptions, changeHandle) {
  383. let panelStyles = `
  384. <style>
  385. .section {
  386. font-size: 16px;
  387. margin-bottom: 10px;
  388. }
  389. .sectionEnd {
  390. border-top: 1px solid #ccc;
  391. margin-top: 10px;
  392. }
  393.  
  394. #panel {
  395. position: fixed;
  396. top: 50%;
  397. left: 50%;
  398. transform: translate(-50%, -50%);
  399. background-color: #333;
  400. color: #fff;
  401. padding: 20px;
  402. border-radius: 5px;
  403. box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
  404. z-index: 999999;
  405. }
  406. .slider-label{
  407. width: 12ch;
  408. }
  409.  
  410. .apply-button {
  411. display: flex;
  412. justify-content: center;
  413. align-items: center;
  414. background-color: #555;
  415. color: white;
  416. border: none;
  417. padding: 8px 12px;
  418. cursor: pointer;
  419. border-radius: 4px;
  420. text-decoration: none;
  421. margin-top: 10px;
  422. margin-left: auto;
  423. }
  424.  
  425. .row {
  426. display: flex;
  427. align-items: center;
  428. margin-bottom: 10px;
  429. }
  430.  
  431. .slider {
  432. flex: 1;
  433. }
  434.  
  435. .slider-value {
  436. margin-left: 10px;
  437. font-size: 14px;
  438. color: #bbb;
  439. width: 4ch;
  440. }
  441.  
  442. .selector {
  443. flex: 1;
  444. margin-right: 10px;
  445. padding: 5px;
  446. border: 1px solid #555;
  447. border-radius: 3px;
  448. background-color: #444;
  449. color: #fff;
  450. }
  451.  
  452. .number-input {
  453. width: 6ch;
  454. padding: 5px;
  455. border: 1px solid #555;
  456. border-radius: 3px;
  457. background-color: #444;
  458. color: #fff;
  459. margin-right: 10px;
  460. margin-left: 5px;
  461. }
  462.  
  463. .text-selector {
  464. width: 10ch;
  465. padding: 5px;
  466. border: 1px solid #555;
  467. border-radius: 3px;
  468. background-color: #444;
  469. color: #fff;
  470. margin-left: 5px;
  471. }
  472.  
  473. .equal-row {
  474. display: flex;
  475. justify-content: space-between;
  476. align-items: center;
  477. }
  478.  
  479. .checkbox-group {
  480. flex: 1;
  481. display: flex;
  482. justify-content: center;
  483. }
  484. </style>
  485. `
  486.  
  487. // Create the setting panel HTML string based on the provided options
  488. function createPanelHTML(options) {
  489. let html = '<div id="panel" style="display: none;">'
  490. options.forEach(option => {
  491. if (option.type === 'section') {
  492. html += `<div class="section">${option.label}</div>`;
  493. } else if (option.type === 'sectionEnd') {
  494. html += `<div class="sectionEnd"></div>`;
  495. } else if (option.type === 'slider') {
  496. html += `<div class="row">
  497. <label class="slider-label" for="${option.id}">${option.label}:</label>
  498. <input type="range" class="slider" id="${option.id}" min="${option.range[0]}" max="${option.range[1]}" step="0.01" value="${currentSetting[option.id] || option.default}">
  499. <span class="slider-value" id="${option.id}Value">${currentSetting[option.id] || option.default}</span>
  500. </div>`;
  501. } else if (option.type === 'equal-row' || option.type === 'row') {
  502. html += `<div class="${option.type}">`;
  503. option.children.forEach(child => {
  504. // Handle checkboxes
  505. if (child.type === 'checkbox') {
  506. const checked = currentSetting[child.id] !== undefined ? currentSetting[child.id] : child.default;
  507. html += `<div class="checkbox-group">
  508. <label for="${child.id}">${child.label}:</label>
  509. <input type="checkbox" id="${child.id}" ${checked ? 'checked' : ''}>
  510. </div>`;
  511. }
  512. // Handle number input
  513. else if (child.type === 'numberInput') {
  514. html += `<label for="${child.id}">${child.label}${child.splitter || ':'}</label>
  515. <input type="number" class="number-input" id="${child.id}" value="${currentSetting[child.id] || child.default}">
  516. `;
  517. if (child.suffixLabel) {
  518. html += `<span>${child.suffixLabel}</span>`
  519. }
  520. }
  521. // Handle text selector
  522. else if (child.type === 'textSelector') {
  523. let currentValue = currentSetting[child.id] || child.default
  524. html += `<label for="${child.id}">${child.label}:</label>
  525. <select class="selector text-selector" id="${child.id}">`;
  526. child.optionText.forEach((text, index) => {
  527. const value = child.optionValue[index];
  528. const selected = currentValue === value ? 'selected' : '';
  529. html += `<option value="${value}" ${selected}>${text}</option>`;
  530. });
  531. html += `</select>`;
  532. }
  533. });
  534. html += `</div>`;
  535. }
  536. });
  537. html += '<button class="apply-button" id="applyButton">应用</button></div>';
  538. return html;
  539. }
  540.  
  541. function createSettingPanel(settingPanelOptions, changeHandle) {
  542.  
  543. document.body.insertAdjacentHTML('beforeend', panelStyles);
  544. const panelHTML = createPanelHTML(settingPanelOptions);
  545. document.body.insertAdjacentHTML('beforeend', panelHTML);
  546.  
  547. const panel = document.getElementById('panel');
  548.  
  549. panel.querySelector('#applyButton').addEventListener('click', () => {
  550. panel.style.display = 'none';
  551. saveLocalSetting('danmakuSetting', currentSetting)
  552. });
  553.  
  554. const sliders = panel.querySelectorAll('.slider');
  555. const sliderValues = panel.querySelectorAll('.slider-value');
  556.  
  557. sliders.forEach((slider, index) => {
  558. slider.addEventListener('input', () => {
  559. sliderValues[index].textContent = slider.value;
  560. changeHandle[slider.id](parseFloat(slider.value), slider.id);
  561. });
  562. });
  563.  
  564. // Handle checkbox changes
  565. const checkboxes = panel.querySelectorAll('input[type="checkbox"]');
  566. checkboxes.forEach(checkbox => {
  567. checkbox.addEventListener('change', () => {
  568. changeHandle[checkbox.id](Number(checkbox.checked), checkbox.id);
  569. });
  570. });
  571.  
  572. // Handle number input changes
  573. const numberInputs = panel.querySelectorAll('.number-input');
  574. numberInputs.forEach(input => {
  575. input.addEventListener('input', () => {
  576. const value = parseFloat(input.value);
  577. if (!isNaN(value)) {
  578. changeHandle[input.id](value, input.id);
  579. }
  580. });
  581. });
  582.  
  583. // Handle text selector changes
  584. const textSelectors = panel.querySelectorAll('.text-selector');
  585. textSelectors.forEach(selector => {
  586. selector.addEventListener('change', () => {
  587. changeHandle[selector.id](selector.value, selector.id);
  588. });
  589. });
  590.  
  591. return panel
  592. }
  593.  
  594.  
  595. let panel = createSettingPanel(settingPanelOptions, changeHandle)
  596. panel.style.display = 'none'
  597. return function () {
  598. if (panel.style.display !== 'block') {
  599. panel.style.display = 'block'
  600. } else {
  601. panel.style.display = 'none'
  602. }
  603. }
  604. })(settingPanelOptions
  605. ,
  606. {
  607. capturePeriodStart(value, id) {
  608. currentSetting[id] = value;
  609. }, capturePeriodEnd(value, id) {
  610. currentSetting[id] = value;
  611. }, splitFileByTime(value, id) {
  612. currentSetting[id] = value;
  613. },
  614. });
  615.  
  616. async function findCidInfo() {
  617. let cid = window.prompt("请输入要查询的cid")
  618. if (!/^\d+$/.exec(cid)) {
  619. alert("请输入一个数字")
  620. return
  621. }
  622. let response = await fetch(`/api/cidinfo?cid=${cid}`)
  623. let body = await response.json()
  624. window.alert((JSON.stringify(body.data)))
  625.  
  626. }
  627.  
  628.  
  629. (function createToolbar(config) {
  630. let html = `
  631. <style>
  632.  
  633. #triggerArea {
  634. position: fixed;
  635. top: 45%;
  636. left: 0;
  637. width: max(5%,50px);
  638. height: 30%;
  639. cursor: pointer;
  640. z-index: 999998;
  641. }
  642.  
  643. #toolbar {
  644. position: fixed;
  645. top: 50%;
  646. left: -250px;
  647. transform: translateY(-50%);
  648. background-color: #333;
  649. color: #fff;
  650. padding: 10px;
  651. border-top-right-radius: 5px;
  652. border-bottom-right-radius: 5px;
  653. cursor: grab;
  654. transition: left 0.3s;
  655. z-index: 999999;
  656. }
  657.  
  658. #toolbar:active {
  659. cursor: grabbing;
  660. }
  661.  
  662. #toolbar button {
  663. display: block;
  664. margin: 5px 0;
  665. padding: 8px;
  666. background-color: #555;
  667. border: none;
  668. color: #fff;
  669. cursor: pointer;
  670. border-radius: 3px;
  671. }
  672. </style>
  673. <div id="triggerArea"></div>
  674. <div id="toolbar"></div>
  675. `
  676. document.body.insertAdjacentHTML('beforeend', html)
  677. const triggerArea = document.getElementById('triggerArea');
  678. const toolbar = document.getElementById('toolbar');
  679. let isDragging = false;
  680. let isExpanded = false;
  681. let startY = 0;
  682. let initialTop = 0;
  683. let currentSetting = getLocalSetting('dfToolbar')
  684. if (currentSetting['offsetTopPercent']) {
  685. toolbar.setAttribute('offsetTop', currentSetting['offsetTopPercent'] * window.innerHeight)
  686. }
  687. console.log('createToolbar', config)
  688. for (let option of Object.keys(config.options)) {
  689. let button = document.createElement("button")
  690. button.innerText = option
  691. button.addEventListener('click', config.options[option])
  692. toolbar.appendChild(button)
  693. }
  694.  
  695.  
  696. function expandToolbar() {
  697. if (!isExpanded) {
  698. toolbar.style.left = '0';
  699. isExpanded = true;
  700. }
  701. }
  702.  
  703. function collapseToolbar() {
  704. if (isExpanded) {
  705. toolbar.style.left = '-250px';
  706. isExpanded = false;
  707. }
  708. }
  709.  
  710. triggerArea.addEventListener('mouseenter', () => {
  711. expandToolbar();
  712. });
  713.  
  714. triggerArea.addEventListener('mouseleave', () => {
  715. collapseToolbar();
  716. if (isDragging) {
  717. isDragging = false
  718. dragEndHandle()
  719. }
  720. });
  721.  
  722. toolbar.addEventListener('mouseenter', () => {
  723. expandToolbar();
  724. });
  725.  
  726. toolbar.addEventListener('mouseleave', () => {
  727. if (!isDragging) {
  728. collapseToolbar();
  729. }
  730. });
  731.  
  732. toolbar.addEventListener('mousedown', (e) => {
  733. if (e.target === toolbar) {
  734. console.log(e.type, e)
  735. isDragging = true;
  736. startY = e.clientY;
  737. initialTop = toolbar.offsetTop;
  738. }
  739. });
  740.  
  741.  
  742. let draggingHandle = (e) => {
  743. if (!isDragging) return;
  744. const deltaY = e.clientY - startY;
  745. toolbar.style.top = `${initialTop + deltaY}px`;
  746. }
  747.  
  748. let dragEndHandle = (e) => {
  749. if (isDragging) {
  750. isDragging = false;
  751. currentSetting.offsetTopPercent = toolbar.offsetTop / window.innerHeight
  752. saveLocalSetting('dfToolbar', currentSetting)
  753. }
  754. }
  755.  
  756. window.addEventListener('mousemove', draggingHandle);
  757. window.addEventListener('mouseup', dragEndHandle);
  758.  
  759. expandToolbar()
  760. setTimeout(collapseToolbar, 3000)
  761. })({
  762. options: {
  763. "下载选项": showSettingPanel,
  764. "CID 反查": findCidInfo,
  765. "AID 查询": aidQuery
  766. }
  767. });
  768. return currentSetting
  769. }
  770.  
  771. function client() {
  772. let registeredTimestamp = new Date().getTime()
  773.  
  774.  
  775. console.log('biliplus script running')
  776.  
  777. function getAid() {
  778. let aid
  779. if (/\/BV/.exec(window.location.href)) {
  780.  
  781. aid = bv2av(/BV[a-zA-Z0-9]+/.exec(window.location.href)[0])
  782. } else {
  783. aid = /av(\d+)/.exec(window.location.href)[1]
  784. }
  785. return Number(aid)
  786. }
  787.  
  788. function xmlunEscape(content) {
  789. return content.replace(/, /g, ';')
  790. .replace(/&amp;/g, '&')
  791. .replace(/&lt;/g, '<')
  792. .replace(/&gt;/g, '>')
  793. .replace(/&apos;/g, "'")
  794. .replace(/&quot;/g, '"')
  795. }
  796.  
  797. let createElement = function (sHtml) {
  798. // 创建一个可复用的包装元素
  799. let recycled = document.createElement('div'),
  800. // 创建标签简易匹配
  801. reg = /^<([a-zA-Z]+)(?=\s|\/>|>)[\s\S]*>$/,
  802. // 某些元素HTML标签必须插入特定的父标签内,才能产生合法元素
  803. // 另规避:ie7-某些元素innerHTML只读
  804. // 创建这些需要包装的父标签hash
  805. hash = {
  806. 'colgroup': 'table',
  807. 'col': 'colgroup',
  808. 'thead': 'table',
  809. 'tfoot': 'table',
  810. 'tbody': 'table',
  811. 'tr': 'tbody',
  812. 'th': 'tr',
  813. 'td': 'tr',
  814. 'optgroup': 'select',
  815. 'option': 'optgroup',
  816. 'legend': 'fieldset'
  817. };
  818. // 闭包重载方法(预定义变量避免重复创建,调用执行更快,成员私有化)
  819. createElement = function (sHtml) {
  820. // 若不包含标签,调用内置方法创建并返回元素
  821. if (!reg.test(sHtml)) {
  822. return document.createElement(sHtml);
  823. }
  824. // hash中是否包含匹配的标签名
  825. let tagName = hash[RegExp.$1.toLowerCase()];
  826. // 若无,向包装元素innerHTML,创建/截取并返回元素
  827. if (!tagName) {
  828. recycled.innerHTML = sHtml;
  829. return recycled.removeChild(recycled.firstChild);
  830. }
  831. // 若匹配hash标签,迭代包装父标签,并保存迭代层次
  832. let deep = 0, element = recycled;
  833. do {
  834. sHtml = '<' + tagName + '>' + sHtml + '</' + tagName + '>';
  835. deep++;
  836. }
  837. while (tagName = hash[tagName]);
  838. element.innerHTML = sHtml;
  839. // 根据迭代层次截取被包装的子元素
  840. do {
  841. element = element.removeChild(element.firstChild);
  842. }
  843. while (--deep > -1);
  844. // 最终返回需要创建的元素
  845. return element;
  846. }
  847. // 执行方法并返回结果
  848. return createElement(sHtml);
  849. }
  850.  
  851. async function parseVideoInfo(aid) {
  852. let videoInfo
  853. try {
  854. let videoPage = await xhrGet('https://www.biliplus.com/video/av' + aid + '/')
  855. videoInfo = JSON.parse(xmlunEscape(/({"id":.*?})\);/.exec(videoPage)[1]))
  856. videoInfo['aid'] = videoInfo['id']
  857. } catch (e) {
  858. console.log(e)
  859. let videoPage = await xhrGet('https://www.biliplus.com/all/video/av' + aid + '/')
  860. let url = /(\/api\/view_all\?.*?)'/.exec(videoPage)[1]
  861. url = 'https://www.biliplus.com' + url
  862. let data = JSON.parse(xmlunEscape(await xhrGet(url)))['data']
  863. videoInfo = data['info']
  864. videoInfo['list'] = data['parts']
  865. }
  866. if (videoInfo.created) {
  867. videoInfo.videoPublishDate = videoInfo.created
  868. }
  869. console.log(videoInfo)
  870. return videoInfo
  871. }
  872.  
  873. (function searchFix() {
  874. if (window.location.href.indexOf('api/do.php') === -1) return
  875.  
  876. function searchOption() {
  877. let searchField = document.querySelector("#searchField > fieldset")
  878. let searchDiv = document.querySelector("#searchField > fieldset > div:nth-child(1)")
  879. searchDiv.insertAdjacentHTML('afterend',
  880. `
  881. <style>
  882. .dropdown {
  883. background-color: #f2f2f2;
  884. padding: 4px;
  885. border-radius: 2px;
  886. }
  887.  
  888. .dropdown option {
  889. padding: 10px;
  890. font-size: 14px;
  891. color: #333;
  892. }
  893.  
  894. .dropdown option:hover {
  895. background-color: #e5e5e5;
  896. }
  897. </style>
  898. <select id="alive-section" class="dropdown">
  899. <option value="连载动画">连载动画</option>
  900. <option value="完结动画">完结动画</option>
  901. <option value="国产动画">国产动画</option>
  902. <option value="欧美电影">欧美电影</option>
  903. <option value="日本电影">日本电影</option>
  904. <option value="国产电影">国产电影</option>
  905. <option value="布袋戏">布袋戏</option>
  906. <option value="国产剧">国产剧</option>
  907. <option value="海外剧">海外剧</option>
  908. <option value="" selected="">视频分区</option>
  909. </select>
  910. <select id="dead-section" class="dropdown">
  911. <option value="连载剧集">连载剧集</option>
  912. <option value="完结剧集">完结剧集</option>
  913. <option value="国产">国产</option>
  914. <option value="日剧">日剧</option>
  915. <option value="美剧">美剧</option>
  916. <option value="其他">其他</option>
  917. <option value="特摄">特摄</option>
  918. <option value="剧场版">剧场版</option>
  919. <option value="" selected="">下架分区</option>
  920. </select>
  921. <select id="poster" class="dropdown">
  922. <option value="928123">哔哩哔哩番剧</option>
  923. <option value="11783021">哔哩哔哩番剧出差</option>
  924. <option value="15773384">哔哩哔哩电影</option>
  925. <option value="4856007">迷影社</option>
  926. <option value="" selected="">UP主</option>
  927. </select>
  928. `
  929. )
  930. let aliveSection = searchField.querySelector("select[id='alive-section']")
  931. let deadSection = searchField.querySelector("select[id='dead-section']")
  932. let poster = searchField.querySelector("select[id='poster']")
  933. let searchInput = document.querySelector("#searchField > fieldset > div:nth-child(1) > input[type=search]")
  934.  
  935. function setSection(section) {
  936. let content = searchInput.value
  937. if (section !== "") {
  938. section = ' @' + section
  939. }
  940. if (/ @\S+/.exec(content)) {
  941. content = content.replace(/ @\S+/, section)
  942. } else
  943. content += section
  944. searchInput.value = content
  945. }
  946.  
  947. function setPoster(uid) {
  948. if (uid !== "") {
  949. uid = ' @m=' + uid
  950. }
  951. let content = searchInput.value
  952. if (/ @m=\d+/.exec(content)) {
  953. content = content.replace(/ @m=\d+/, uid)
  954. } else
  955. content += uid
  956. searchInput.value = content
  957. }
  958.  
  959. aliveSection.addEventListener('change', (event) => {
  960. if (deadSection.value !== "") {
  961. deadSection.value = ""
  962. }
  963. setSection(event.target.value)
  964. })
  965. deadSection.addEventListener('change', (event) => {
  966. if (aliveSection.value !== "") {
  967. aliveSection.value = ""
  968. }
  969. setSection(event.target.value)
  970. })
  971. poster.addEventListener('change', (event) => {
  972. setPoster(event.target.value)
  973. })
  974. }
  975.  
  976. searchOption()
  977. unsafeWindow.openOrigin = unsafeWindow.open
  978. unsafeWindow.open = function (link) {
  979. console.log('window.open', link)
  980. if (link) {
  981. unsafeWindow.openOrigin(link)
  982. }
  983. }
  984. let getjson = unsafeWindow.parent.getjsonReal = unsafeWindow.parent.getjson
  985. let aidList = []
  986. let irrelevantArchive = []
  987. let allArchive = []
  988.  
  989. async function joinCallback(url, callback, n) {
  990. if (url[0] === '/')
  991. url = 'https:' + url
  992. let word = /word=(.*?)(&|$)/.exec(url)[1]
  993. let wordList = []
  994. for (let keyword of decodeURIComponent(word).replace(/([^ ])@/, '$1 @').split(' ')) {
  995. if (keyword[0] !== '@') {
  996. wordList.push(keyword)
  997. }
  998. }
  999. let pn = /p=(\d+)/.exec(url)
  1000. pn = pn ? pn[1] : '1'
  1001. if (pn === '1') {
  1002. aidList = []
  1003. irrelevantArchive = []
  1004. allArchive = []
  1005. }
  1006.  
  1007. let searchResult = JSON.parse(await xhrGet(url))
  1008. let archive = []
  1009. searchResult['data']['items']['archive'].forEach(function (item) {
  1010. if (item.goto === 'av') {
  1011. if (aidList.indexOf(item.param) === -1) {
  1012. aidList.push(item.param)
  1013. let isRelevant = false
  1014. for (let keyword of wordList) {
  1015. for (let key of ['title', 'desc']) {
  1016. if (item[key].indexOf(keyword) !== -1) {
  1017. isRelevant = true
  1018. }
  1019. }
  1020. }
  1021. if (isRelevant) {
  1022. archive.push(item)
  1023. } else {
  1024. irrelevantArchive.push(item)
  1025. }
  1026. allArchive.push(item)
  1027. }
  1028. } else {
  1029. archive.push(item)
  1030. }
  1031. })
  1032.  
  1033. try {
  1034. let aidSearchUrl = '/api/search?word=' + word + '&page=' + pn
  1035. let aidSearchResult = JSON.parse((await xhrGet(aidSearchUrl)))['result']
  1036. aidSearchResult.forEach(function (video) {
  1037. if (aidList.indexOf(video.aid) === -1) {
  1038. let item = {
  1039. author: video.author,
  1040. cover: video.pic,
  1041. created: new Date(video.created.replace(/-/g, '/')).getTime() / 1000,
  1042. review: video.review,
  1043. desc: video.description,
  1044. goto: "av",
  1045. param: video.aid,
  1046. play: video.play,
  1047. title: video.title,
  1048. }
  1049.  
  1050. let isRelevant = false
  1051. for (let keyword of wordList) {
  1052. for (let key of ['title', 'desc']) {
  1053. if (item[key].indexOf(keyword) !== -1) {
  1054. isRelevant = true
  1055. }
  1056. }
  1057. }
  1058. if (isRelevant) {
  1059. archive.push(item)
  1060. } else {
  1061. irrelevantArchive.push(item)
  1062. }
  1063. allArchive.push(item)
  1064. }
  1065. })
  1066. } catch (e) {
  1067. console.log(e)
  1068. }
  1069.  
  1070. if (archive.length === 0) {
  1071. archive = irrelevantArchive
  1072. irrelevantArchive = []
  1073. }
  1074. searchResult['data']['items']['archive'] = archive
  1075. callback(searchResult, n)
  1076. return
  1077. }
  1078.  
  1079.  
  1080. unsafeWindow.getjson = unsafeWindow.parent.getjson = function (url, callback, n) {
  1081. if (url.indexOf("search_api") !== -1 && url.indexOf("source=biliplus") !== -1) {
  1082. try {
  1083.  
  1084. return joinCallback(url, callback, n)
  1085. } catch (e) {
  1086. console.log(e)
  1087. return getjson(url, callback, n)
  1088. }
  1089. } else return getjson(url, callback, n)
  1090.  
  1091. };
  1092. unsafeWindow.doSearch()
  1093.  
  1094.  
  1095. broadcastChannel.addEventListener('message', function (event) {
  1096. console.log(event.data)
  1097. if (event.data.type === 'aidComplete') {
  1098. let elem = document.querySelector('[id="av' + event.data.aid + '"]')
  1099. if (elem) elem.textContent = '下载完成'
  1100. }
  1101. if (event.data.type === 'aidDownloaded') {
  1102. let elem = document.querySelector('[id="av' + event.data.aid + '"]')
  1103. if (elem) elem.textContent = '已下载'
  1104. }
  1105. if (event.data.type === 'aidStart') {
  1106. let elem = document.querySelector('[id="av' + event.data.aid + '"]')
  1107. if (elem) elem.textContent = '开始下载'
  1108. }
  1109. if (event.data.type === 'cidComplete') {
  1110. let elem = document.querySelector('[id="av' + event.data.aid + '"]')
  1111. if (elem) elem.textContent = event.data.progress + "%"
  1112. }
  1113. })
  1114.  
  1115. document.addEventListener("DOMNodeInserted", async (msg) => {
  1116. if (msg.target.nodeName === '#text') {
  1117. let aidElem = msg.target.parentElement.parentElement
  1118. .querySelector('div[class="video-card-desc"]')
  1119. if (!aidElem) {
  1120. return
  1121. }
  1122. console.log(aidElem)
  1123. let link = msg.target.parentElement.parentElement.parentElement.getAttribute("data-link")
  1124. if (link) {
  1125. console.log(link)
  1126. msg.target.parentElement.parentElement.parentElement.removeAttribute("data-link")
  1127. msg.target.parentElement.parentElement.parentElement.addEventListener('click', async function (event) {
  1128. console.log(event)
  1129. event.preventDefault()
  1130. if (event.target.className !== 'download') {
  1131. unsafeWindow.openOrigin(link)
  1132. }
  1133. })
  1134. }
  1135.  
  1136. let aid = parseInt(aidElem.textContent.slice(2))
  1137. if (!aidElem.querySelector('[class="download"]')) {
  1138. let downloadButton = createElement(
  1139. '<div class="download" style="display:inline-block;float:right;border-radius:5px;border:1px solid #AAA;' +
  1140. 'background:#DDD;padding:8px 20px;cursor:pointer" id="av' + aid + '">下载弹幕</div>')
  1141. window.moved = true
  1142.  
  1143. downloadButton.addEventListener('click', async function (event) {
  1144. event.preventDefault()
  1145. console.log('download', aid)
  1146. if (downloadButton.textContent !== '下载弹幕') return
  1147. downloadButton.textContent = '等待下载'
  1148. let videoInfo = await parseVideoInfo(aid)
  1149. broadcastChannel.postMessage({
  1150. type: 'biliplusDownloadDanmakuVideo',
  1151. videoInfo: videoInfo,
  1152. timestamp: registeredTimestamp
  1153. })
  1154. })
  1155. aidElem.appendChild(downloadButton)
  1156. }
  1157. let timeago = msg.target.parentElement
  1158. for (let video of allArchive) {
  1159. if (video.param === aid && video.goto === 'av') {
  1160. let text = timeago.getAttribute('title') + ' 播放:' + video['play']
  1161. if (video['danmaku']) text += ' 弹幕:' + video['danmaku']
  1162. if (video['review']) text += ' 评论:' + video['review']
  1163. timeago.textContent = text
  1164. }
  1165. }
  1166. }
  1167. })
  1168.  
  1169. })();
  1170.  
  1171. (function historyFix() {
  1172. const registry = new ObjectRegistry();
  1173.  
  1174. if (window.location.href.indexOf('/video/') === -1) return
  1175. unsafeWindow.downloadVideoDanmaku = async function (aid, videoInfo) {
  1176. registry.register('downloadVideoDanmaku')
  1177. if (!videoInfo) {
  1178. if (unsafeWindow.videoInfo) {
  1179. videoInfo = unsafeWindow.videoInfo
  1180. } else {
  1181. if (!aid) {
  1182. aid = getAid()
  1183. }
  1184. videoInfo = await parseVideoInfo(aid)
  1185. }
  1186. }
  1187. console.log('downloadVideoDanmaku', videoInfo)
  1188.  
  1189. broadcastChannel.postMessage({
  1190. type: 'biliplusDownloadDanmakuVideo',
  1191. videoInfo: videoInfo,
  1192. timestamp: registeredTimestamp
  1193. })
  1194. }
  1195.  
  1196. function getEpisodePublishDate(episode) {
  1197. let dateTimeString = episode.pub_real_time || episode.ctime
  1198. if (!dateTimeString) {
  1199. return null
  1200. }
  1201. const unixTimestamp = Date.parse(dateTimeString);
  1202. return Math.floor(unixTimestamp / 1000); // Convert milliseconds to seconds
  1203. }
  1204.  
  1205.  
  1206. document.addEventListener("DOMNodeInserted", async (msg) => {
  1207. if (msg.target.id) {
  1208. switch (msg.target.id) {
  1209. case 'danmaku_container': {
  1210. let historyButton = msg.target.querySelector('a[href^="/open/moepus.powered"]')
  1211. let cid = /#(\d+)/.exec(historyButton.getAttribute('href'))[1]
  1212. historyButton.onclick = async function () {
  1213.  
  1214. console.log('biliplusDownloadDanmaku', {
  1215. 'cid': cid,
  1216. 'title': document.querySelector('[class="videotitle"]').textContent + ' ' + document.querySelector('[id="cid_' + cid + '"]').innerText,
  1217. 'timestamp': registeredTimestamp
  1218. })
  1219. broadcastChannel.postMessage(
  1220. {
  1221. type: 'biliplusDownloadDanmaku',
  1222. cid: cid,
  1223. title: document.querySelector('[class="videotitle"]').textContent + ' '
  1224. + document.querySelector('[id="cid_' + cid + '"]').innerText,
  1225.  
  1226. timestamp: registeredTimestamp
  1227. }
  1228. )
  1229. }
  1230. historyButton.removeAttribute('href')
  1231.  
  1232. let commentButton = msg.target.querySelector('a[href^="https://comment.bilibili.com"]')
  1233. commentButton.removeAttribute('href')
  1234. commentButton.removeAttribute('onClick')
  1235. commentButton.addEventListener('click', async function () {
  1236. registry.register('commentButton' + cid)
  1237. let commentText = await xhrGet("/danmaku/" + cid + ".xml")
  1238. if (!commentText || commentText.indexOf("<state>2</state>") !== -1) {
  1239. broadcastChannel.postMessage(
  1240. {
  1241. type: 'biliplusDownloadDanmaku',
  1242. ndanmu: /<maxlimit>(\d+)<\/maxlimit>/.exec(commentText)?.[1],
  1243. cid: cid,
  1244. title: document.querySelector('[class="videotitle"]').textContent + ' '
  1245. + document.querySelector('[id="cid_' + cid + '"]').innerText,
  1246. history: false,
  1247. timestamp: registeredTimestamp
  1248. }
  1249. )
  1250. } else {
  1251. downloadFile(cid + '.xml', commentText)
  1252. }
  1253. })
  1254. break
  1255. }
  1256. case 'favorite': {
  1257. msg.target.parentElement.appendChild(createElement(
  1258. '<span id="downloadDanmaku"><a href="javascript:" onclick="window.downloadVideoDanmaku()">' +
  1259. '<div class="solidbox pink" id="av' + getAid() + '">下载视频弹幕</div></a></span>'))
  1260. break
  1261. }
  1262. case 'part1': {
  1263. msg.target.parentElement.insertBefore(createElement('<div class="solidbox pointer" onclick="window.downloadVideoDanmaku()">下载视频弹幕</div>'), msg.target)
  1264. break
  1265. }
  1266. case 'bgBlur': {
  1267. let bangumi = unsafeWindow.bangumi
  1268. if (!bangumi.isBangumi) break
  1269. let bangumiList = document.querySelector("#bangumi_list")
  1270. bangumiList.insertAdjacentHTML(
  1271. 'beforeend', '<div class="solidbox pointer">下载剧集弹幕</div>'
  1272. )
  1273. bangumiList.lastChild.addEventListener('click', function (event) {
  1274. registry.register('downloadBangumiDanmaku')
  1275. console.log(event.target)
  1276. if (event.target.textContent !== '下载中') {
  1277. event.target.textContent = "下载中"
  1278. } else {
  1279. return
  1280. }
  1281. let apiCache = bangumi.apiCache
  1282. let response = apiCache[Object.keys(apiCache)[0]].result
  1283. let videoInfo = {
  1284. aid: 'ss' + response.season_id,
  1285. title: response.title,
  1286. list: [],
  1287. detail: response,
  1288. }
  1289. for (let episode of response.episodes) {
  1290. if (episode.episode_type === -1
  1291. || episode.section_type === 1
  1292. || episode.section_type === 2) continue
  1293. let partInfo = {
  1294. page: episode.index ? episode.index : episode.title,
  1295. part: episode.index_title ? episode.index_title : episode.long_title,
  1296. cid: episode.cid,
  1297. duration: episode.duration,
  1298. videoPublishDate: getEpisodePublishDate(episode)
  1299. }
  1300. videoInfo.list.push(partInfo)
  1301. }
  1302. unsafeWindow.downloadVideoDanmaku(null, videoInfo)
  1303. })
  1304. }
  1305. }
  1306. }
  1307. })
  1308. })();
  1309. }
  1310.  
  1311.  
  1312. function server() {
  1313.  
  1314. let videoPublishDate = null
  1315.  
  1316. let [downloadDanmaku, downloadDanmakuToZip, allProtobufDanmu] = (function () {
  1317. !function (z) {
  1318. var y = {
  1319. 1: [function (p, w) {
  1320. w.exports = function (h, m) {
  1321. for (var n = Array(arguments.length - 1), e = 0, d = 2, a = !0; d < arguments.length;) n[e++] = arguments[d++];
  1322. return new Promise(function (b, c) {
  1323. n[e] = function (k) {
  1324. if (a) if (a = !1, k) c(k); else {
  1325. for (var l = Array(arguments.length - 1), q = 0; q < l.length;) l[q++] = arguments[q];
  1326. b.apply(null, l)
  1327. }
  1328. };
  1329. try {
  1330. h.apply(m || null, n)
  1331. } catch (k) {
  1332. a && (a = !1, c(k))
  1333. }
  1334. })
  1335. }
  1336. }, {}], 2: [function (p, w, h) {
  1337. h.length = function (e) {
  1338. var d = e.length;
  1339. if (!d) return 0;
  1340. for (var a = 0; 1 < --d % 4 && "=" === e.charAt(d);) ++a;
  1341. return Math.ceil(3 *
  1342. e.length) / 4 - a
  1343. };
  1344. var m = Array(64), n = Array(123);
  1345. for (p = 0; 64 > p;) n[m[p] = 26 > p ? p + 65 : 52 > p ? p + 71 : 62 > p ? p - 4 : p - 59 | 43] = p++;
  1346. h.encode = function (e, d, a) {
  1347. for (var b, c = null, k = [], l = 0, q = 0; d < a;) {
  1348. var f = e[d++];
  1349. switch (q) {
  1350. case 0:
  1351. k[l++] = m[f >> 2];
  1352. b = (3 & f) << 4;
  1353. q = 1;
  1354. break;
  1355. case 1:
  1356. k[l++] = m[b | f >> 4];
  1357. b = (15 & f) << 2;
  1358. q = 2;
  1359. break;
  1360. case 2:
  1361. k[l++] = m[b | f >> 6], k[l++] = m[63 & f], q = 0
  1362. }
  1363. 8191 < l && ((c || (c = [])).push(String.fromCharCode.apply(String, k)), l = 0)
  1364. }
  1365. return q && (k[l++] = m[b], k[l++] = 61, 1 === q && (k[l++] = 61)), c ? (l && c.push(String.fromCharCode.apply(String, k.slice(0, l))),
  1366. c.join("")) : String.fromCharCode.apply(String, k.slice(0, l))
  1367. };
  1368. h.decode = function (e, d, a) {
  1369. for (var b, c = a, k = 0, l = 0; l < e.length;) {
  1370. var q = e.charCodeAt(l++);
  1371. if (61 === q && 1 < k) break;
  1372. if ((q = n[q]) === z) throw Error("invalid encoding");
  1373. switch (k) {
  1374. case 0:
  1375. b = q;
  1376. k = 1;
  1377. break;
  1378. case 1:
  1379. d[a++] = b << 2 | (48 & q) >> 4;
  1380. b = q;
  1381. k = 2;
  1382. break;
  1383. case 2:
  1384. d[a++] = (15 & b) << 4 | (60 & q) >> 2;
  1385. b = q;
  1386. k = 3;
  1387. break;
  1388. case 3:
  1389. d[a++] = (3 & b) << 6 | q, k = 0
  1390. }
  1391. }
  1392. if (1 === k) throw Error("invalid encoding");
  1393. return a - c
  1394. };
  1395. h.test = function (e) {
  1396. return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)
  1397. }
  1398. },
  1399. {}], 3: [function (p, w) {
  1400. function h() {
  1401. this.t = {}
  1402. }
  1403.  
  1404. (w.exports = h).prototype.on = function (m, n, e) {
  1405. return (this.t[m] || (this.t[m] = [])).push({fn: n, ctx: e || this}), this
  1406. };
  1407. h.prototype.off = function (m, n) {
  1408. if (m === z) this.t = {}; else if (n === z) this.t[m] = []; else for (var e = this.t[m], d = 0; d < e.length;) e[d].fn === n ? e.splice(d, 1) : ++d;
  1409. return this
  1410. };
  1411. h.prototype.emit = function (m) {
  1412. var n = this.t[m];
  1413. if (n) {
  1414. for (var e = [], d = 1; d < arguments.length;) e.push(arguments[d++]);
  1415. for (d = 0; d < n.length;) n[d].fn.apply(n[d++].ctx, e)
  1416. }
  1417. return this
  1418. }
  1419. }, {}], 4: [function (p,
  1420. w) {
  1421. function h(a) {
  1422. return "undefined" != typeof Float32Array ? function () {
  1423. function b(v, g, t) {
  1424. q[0] = v;
  1425. g[t] = f[0];
  1426. g[t + 1] = f[1];
  1427. g[t + 2] = f[2];
  1428. g[t + 3] = f[3]
  1429. }
  1430.  
  1431. function c(v, g, t) {
  1432. q[0] = v;
  1433. g[t] = f[3];
  1434. g[t + 1] = f[2];
  1435. g[t + 2] = f[1];
  1436. g[t + 3] = f[0]
  1437. }
  1438.  
  1439. function k(v, g) {
  1440. return f[0] = v[g], f[1] = v[g + 1], f[2] = v[g + 2], f[3] = v[g + 3], q[0]
  1441. }
  1442.  
  1443. function l(v, g) {
  1444. return f[3] = v[g], f[2] = v[g + 1], f[1] = v[g + 2], f[0] = v[g + 3], q[0]
  1445. }
  1446.  
  1447. var q = new Float32Array([-0]), f = new Uint8Array(q.buffer), u = 128 === f[3];
  1448. a.writeFloatLE = u ? b : c;
  1449. a.writeFloatBE = u ? c : b;
  1450. a.readFloatLE = u ? k : l;
  1451. a.readFloatBE =
  1452. u ? l : k
  1453. }() : function () {
  1454. function b(k, l, q, f) {
  1455. var u = 0 > l ? 1 : 0;
  1456. if (u && (l = -l), 0 === l) k(0 < 1 / l ? 0 : 2147483648, q, f); else if (isNaN(l)) k(2143289344, q, f); else if (3.4028234663852886E38 < l) k((u << 31 | 2139095040) >>> 0, q, f); else if (1.1754943508222875E-38 > l) k((u << 31 | Math.round(l / 1.401298464324817E-45)) >>> 0, q, f); else {
  1457. var v = Math.floor(Math.log(l) / Math.LN2);
  1458. k((u << 31 | v + 127 << 23 | 8388607 & Math.round(l * Math.pow(2, -v) * 8388608)) >>> 0, q, f)
  1459. }
  1460. }
  1461.  
  1462. function c(k, l, q) {
  1463. q = k(l, q);
  1464. k = 2 * (q >> 31) + 1;
  1465. l = q >>> 23 & 255;
  1466. q &= 8388607;
  1467. return 255 === l ? q ? NaN : 1 / 0 * k : 0 === l ?
  1468. 1.401298464324817E-45 * k * q : k * Math.pow(2, l - 150) * (q + 8388608)
  1469. }
  1470.  
  1471. a.writeFloatLE = b.bind(null, m);
  1472. a.writeFloatBE = b.bind(null, n);
  1473. a.readFloatLE = c.bind(null, e);
  1474. a.readFloatBE = c.bind(null, d)
  1475. }(), "undefined" != typeof Float64Array ? function () {
  1476. function b(v, g, t) {
  1477. q[0] = v;
  1478. g[t] = f[0];
  1479. g[t + 1] = f[1];
  1480. g[t + 2] = f[2];
  1481. g[t + 3] = f[3];
  1482. g[t + 4] = f[4];
  1483. g[t + 5] = f[5];
  1484. g[t + 6] = f[6];
  1485. g[t + 7] = f[7]
  1486. }
  1487.  
  1488. function c(v, g, t) {
  1489. q[0] = v;
  1490. g[t] = f[7];
  1491. g[t + 1] = f[6];
  1492. g[t + 2] = f[5];
  1493. g[t + 3] = f[4];
  1494. g[t + 4] = f[3];
  1495. g[t + 5] = f[2];
  1496. g[t + 6] = f[1];
  1497. g[t + 7] = f[0]
  1498. }
  1499.  
  1500. function k(v, g) {
  1501. return f[0] = v[g], f[1] = v[g +
  1502. 1], f[2] = v[g + 2], f[3] = v[g + 3], f[4] = v[g + 4], f[5] = v[g + 5], f[6] = v[g + 6], f[7] = v[g + 7], q[0]
  1503. }
  1504.  
  1505. function l(v, g) {
  1506. return f[7] = v[g], f[6] = v[g + 1], f[5] = v[g + 2], f[4] = v[g + 3], f[3] = v[g + 4], f[2] = v[g + 5], f[1] = v[g + 6], f[0] = v[g + 7], q[0]
  1507. }
  1508.  
  1509. var q = new Float64Array([-0]), f = new Uint8Array(q.buffer), u = 128 === f[7];
  1510. a.writeDoubleLE = u ? b : c;
  1511. a.writeDoubleBE = u ? c : b;
  1512. a.readDoubleLE = u ? k : l;
  1513. a.readDoubleBE = u ? l : k
  1514. }() : function () {
  1515. function b(k, l, q, f, u, v) {
  1516. var g = 0 > f ? 1 : 0;
  1517. if (g && (f = -f), 0 === f) k(0, u, v + l), k(0 < 1 / f ? 0 : 2147483648, u, v + q); else if (isNaN(f)) k(0, u, v + l), k(2146959360,
  1518. u, v + q); else if (1.7976931348623157E308 < f) k(0, u, v + l), k((g << 31 | 2146435072) >>> 0, u, v + q); else if (2.2250738585072014E-308 > f) k((f /= 4.9E-324) >>> 0, u, v + l), k((g << 31 | f / 4294967296) >>> 0, u, v + q); else {
  1519. var t = Math.floor(Math.log(f) / Math.LN2);
  1520. 1024 === t && (t = 1023);
  1521. k(4503599627370496 * (f *= Math.pow(2, -t)) >>> 0, u, v + l);
  1522. k((g << 31 | t + 1023 << 20 | 1048576 * f & 1048575) >>> 0, u, v + q)
  1523. }
  1524. }
  1525.  
  1526. function c(k, l, q, f, u) {
  1527. l = k(f, u + l);
  1528. f = k(f, u + q);
  1529. k = 2 * (f >> 31) + 1;
  1530. q = f >>> 20 & 2047;
  1531. l = 4294967296 * (1048575 & f) + l;
  1532. return 2047 === q ? l ? NaN : 1 / 0 * k : 0 === q ? 4.9E-324 * k * l : k * Math.pow(2,
  1533. q - 1075) * (l + 4503599627370496)
  1534. }
  1535.  
  1536. a.writeDoubleLE = b.bind(null, m, 0, 4);
  1537. a.writeDoubleBE = b.bind(null, n, 4, 0);
  1538. a.readDoubleLE = c.bind(null, e, 0, 4);
  1539. a.readDoubleBE = c.bind(null, d, 4, 0)
  1540. }(), a
  1541. }
  1542.  
  1543. function m(a, b, c) {
  1544. b[c] = 255 & a;
  1545. b[c + 1] = a >>> 8 & 255;
  1546. b[c + 2] = a >>> 16 & 255;
  1547. b[c + 3] = a >>> 24
  1548. }
  1549.  
  1550. function n(a, b, c) {
  1551. b[c] = a >>> 24;
  1552. b[c + 1] = a >>> 16 & 255;
  1553. b[c + 2] = a >>> 8 & 255;
  1554. b[c + 3] = 255 & a
  1555. }
  1556.  
  1557. function e(a, b) {
  1558. return (a[b] | a[b + 1] << 8 | a[b + 2] << 16 | a[b + 3] << 24) >>> 0
  1559. }
  1560.  
  1561. function d(a, b) {
  1562. return (a[b] << 24 | a[b + 1] << 16 | a[b + 2] << 8 | a[b + 3]) >>> 0
  1563. }
  1564.  
  1565. w.exports = h(h)
  1566. }, {}], 5: [function (p, w, h) {
  1567. w.exports =
  1568. function (m) {
  1569. try {
  1570. var n = eval("require")(m);
  1571. if (n && (n.length || Object.keys(n).length)) return n
  1572. } catch (e) {
  1573. }
  1574. return null
  1575. }
  1576. }, {}], 6: [function (p, w) {
  1577. w.exports = function (h, m, n) {
  1578. var e = n || 8192, d = e >>> 1, a = null, b = e;
  1579. return function (c) {
  1580. if (1 > c || d < c) return h(c);
  1581. e < b + c && (a = h(e), b = 0);
  1582. c = m.call(a, b, b += c);
  1583. return 7 & b && (b = 1 + (7 | b)), c
  1584. }
  1585. }
  1586. }, {}], 7: [function (p, w, h) {
  1587. h.length = function (m) {
  1588. for (var n = 0, e = 0, d = 0; d < m.length; ++d) 128 > (e = m.charCodeAt(d)) ? n += 1 : 2048 > e ? n += 2 : 55296 == (64512 & e) && 56320 == (64512 & m.charCodeAt(d + 1)) ? (++d, n += 4) : n += 3;
  1589. return n
  1590. };
  1591. h.read = function (m, n, e) {
  1592. if (1 > e - n) return "";
  1593. for (var d, a = null, b = [], c = 0; n < e;) 128 > (d = m[n++]) ? b[c++] = d : 191 < d && 224 > d ? b[c++] = (31 & d) << 6 | 63 & m[n++] : 239 < d && 365 > d ? (d = ((7 & d) << 18 | (63 & m[n++]) << 12 | (63 & m[n++]) << 6 | 63 & m[n++]) - 65536, b[c++] = 55296 + (d >> 10), b[c++] = 56320 + (1023 & d)) : b[c++] = (15 & d) << 12 | (63 & m[n++]) << 6 | 63 & m[n++], 8191 < c && ((a || (a = [])).push(String.fromCharCode.apply(String, b)), c = 0);
  1594. return a ? (c && a.push(String.fromCharCode.apply(String, b.slice(0, c))), a.join("")) : String.fromCharCode.apply(String, b.slice(0, c))
  1595. };
  1596. h.write =
  1597. function (m, n, e) {
  1598. for (var d, a, b = e, c = 0; c < m.length; ++c) 128 > (d = m.charCodeAt(c)) ? n[e++] = d : (2048 > d ? n[e++] = d >> 6 | 192 : (55296 == (64512 & d) && 56320 == (64512 & (a = m.charCodeAt(c + 1))) ? (d = 65536 + ((1023 & d) << 10) + (1023 & a), ++c, n[e++] = d >> 18 | 240, n[e++] = d >> 12 & 63 | 128) : n[e++] = d >> 12 | 224, n[e++] = d >> 6 & 63 | 128), n[e++] = 63 & d | 128);
  1599. return e - b
  1600. }
  1601. }, {}], 8: [function (p, w, h) {
  1602. function m() {
  1603. n.Reader.n(n.BufferReader);
  1604. n.util.n()
  1605. }
  1606.  
  1607. var n = h;
  1608. n.build = "minimal";
  1609. n.Writer = p(16);
  1610. n.BufferWriter = p(17);
  1611. n.Reader = p(9);
  1612. n.BufferReader = p(10);
  1613. n.util = p(15);
  1614. n.rpc = p(12);
  1615. n.roots = p(11);
  1616. n.configure = m;
  1617. n.Writer.n(n.BufferWriter);
  1618. m()
  1619. }, {10: 10, 11: 11, 12: 12, 15: 15, 16: 16, 17: 17, 9: 9}], 9: [function (p, w) {
  1620. function h(f, u) {
  1621. return RangeError("index out of range: " + f.pos + " + " + (u || 1) + " > " + f.len)
  1622. }
  1623.  
  1624. function m(f) {
  1625. this.buf = f;
  1626. this.pos = 0;
  1627. this.len = f.length
  1628. }
  1629.  
  1630. function n() {
  1631. var f = new c(0, 0), u = 0;
  1632. if (!(4 < this.len - this.pos)) {
  1633. for (; 3 > u; ++u) {
  1634. if (this.pos >= this.len) throw h(this);
  1635. if (f.lo = (f.lo | (127 & this.buf[this.pos]) << 7 * u) >>> 0, 128 > this.buf[this.pos++]) return f
  1636. }
  1637. return f.lo = (f.lo | (127 & this.buf[this.pos++]) <<
  1638. 7 * u) >>> 0, f
  1639. }
  1640. for (; 4 > u; ++u) if (f.lo = (f.lo | (127 & this.buf[this.pos]) << 7 * u) >>> 0, 128 > this.buf[this.pos++]) return f;
  1641. if (f.lo = (f.lo | (127 & this.buf[this.pos]) << 28) >>> 0, f.hi = (f.hi | (127 & this.buf[this.pos]) >> 4) >>> 0, 128 > this.buf[this.pos++]) return f;
  1642. if (u = 0, 4 < this.len - this.pos) for (; 5 > u; ++u) {
  1643. if (f.hi = (f.hi | (127 & this.buf[this.pos]) << 7 * u + 3) >>> 0, 128 > this.buf[this.pos++]) return f
  1644. } else for (; 5 > u; ++u) {
  1645. if (this.pos >= this.len) throw h(this);
  1646. if (f.hi = (f.hi | (127 & this.buf[this.pos]) << 7 * u + 3) >>> 0, 128 > this.buf[this.pos++]) return f
  1647. }
  1648. throw Error("invalid varint encoding");
  1649. }
  1650.  
  1651. function e(f, u) {
  1652. return (f[u - 4] | f[u - 3] << 8 | f[u - 2] << 16 | f[u - 1] << 24) >>> 0
  1653. }
  1654.  
  1655. function d() {
  1656. if (this.pos + 8 > this.len) throw h(this, 8);
  1657. return new c(e(this.buf, this.pos += 4), e(this.buf, this.pos += 4))
  1658. }
  1659.  
  1660. w.exports = m;
  1661. var a, b = p(15), c = b.LongBits, k = b.utf8, l,
  1662. q = "undefined" != typeof Uint8Array ? function (f) {
  1663. if (f instanceof Uint8Array || Array.isArray(f)) return new m(f);
  1664. throw Error("illegal buffer");
  1665. } : function (f) {
  1666. if (Array.isArray(f)) return new m(f);
  1667. throw Error("illegal buffer");
  1668. };
  1669. m.create = b.Buffer ? function (f) {
  1670. return (m.create = function (u) {
  1671. return b.Buffer.isBuffer(u) ?
  1672. new a(u) : q(u)
  1673. })(f)
  1674. } : q;
  1675. m.prototype.i = b.Array.prototype.subarray || b.Array.prototype.slice;
  1676. m.prototype.uint32 = (l = 4294967295, function () {
  1677. if ((l = (127 & this.buf[this.pos]) >>> 0, 128 > this.buf[this.pos++]) || (l = (l | (127 & this.buf[this.pos]) << 7) >>> 0, 128 > this.buf[this.pos++]) || (l = (l | (127 & this.buf[this.pos]) << 14) >>> 0, 128 > this.buf[this.pos++]) || (l = (l | (127 & this.buf[this.pos]) << 21) >>> 0, 128 > this.buf[this.pos++]) || (l = (l | (15 & this.buf[this.pos]) << 28) >>> 0, 128 > this.buf[this.pos++])) return l;
  1678. if ((this.pos += 5) > this.len) throw this.pos =
  1679. this.len, h(this, 10);
  1680. return l
  1681. });
  1682. m.prototype.int32 = function () {
  1683. return 0 | this.uint32()
  1684. };
  1685. m.prototype.sint32 = function () {
  1686. var f = this.uint32();
  1687. return f >>> 1 ^ -(1 & f) | 0
  1688. };
  1689. m.prototype.bool = function () {
  1690. return 0 !== this.uint32()
  1691. };
  1692. m.prototype.fixed32 = function () {
  1693. if (this.pos + 4 > this.len) throw h(this, 4);
  1694. return e(this.buf, this.pos += 4)
  1695. };
  1696. m.prototype.sfixed32 = function () {
  1697. if (this.pos + 4 > this.len) throw h(this, 4);
  1698. return 0 | e(this.buf, this.pos += 4)
  1699. };
  1700. m.prototype["float"] = function () {
  1701. if (this.pos + 4 > this.len) throw h(this, 4);
  1702. var f = b["float"].readFloatLE(this.buf,
  1703. this.pos);
  1704. return this.pos += 4, f
  1705. };
  1706. m.prototype["double"] = function () {
  1707. if (this.pos + 8 > this.len) throw h(this, 4);
  1708. var f = b["float"].readDoubleLE(this.buf, this.pos);
  1709. return this.pos += 8, f
  1710. };
  1711. m.prototype.bytes = function () {
  1712. var f = this.uint32(), u = this.pos, v = this.pos + f;
  1713. if (v > this.len) throw h(this, f);
  1714. return this.pos += f, Array.isArray(this.buf) ? this.buf.slice(u, v) : u === v ? new this.buf.constructor(0) : this.i.call(this.buf, u, v)
  1715. };
  1716. m.prototype.string = function () {
  1717. var f = this.bytes();
  1718. return k.read(f, 0, f.length)
  1719. };
  1720. m.prototype.skip = function (f) {
  1721. if ("number" ==
  1722. typeof f) {
  1723. if (this.pos + f > this.len) throw h(this, f);
  1724. this.pos += f
  1725. } else {
  1726. do if (this.pos >= this.len) throw h(this); while (128 & this.buf[this.pos++])
  1727. }
  1728. return this
  1729. };
  1730. m.prototype.skipType = function (f) {
  1731. switch (f) {
  1732. case 0:
  1733. this.skip();
  1734. break;
  1735. case 1:
  1736. this.skip(8);
  1737. break;
  1738. case 2:
  1739. this.skip(this.uint32());
  1740. break;
  1741. case 3:
  1742. for (; 4 != (f = 7 & this.uint32());) this.skipType(f);
  1743. break;
  1744. case 5:
  1745. this.skip(4);
  1746. break;
  1747. default:
  1748. throw Error("invalid wire type " + f + " at offset " + this.pos);
  1749. }
  1750. return this
  1751. };
  1752. m.n = function (f) {
  1753. a = f;
  1754. var u = b.Long ? "toLong" : "toNumber";
  1755. b.merge(m.prototype, {
  1756. int64: function () {
  1757. return n.call(this)[u](!1)
  1758. }, uint64: function () {
  1759. return n.call(this)[u](!0)
  1760. }, sint64: function () {
  1761. return n.call(this).zzDecode()[u](!1)
  1762. }, fixed64: function () {
  1763. return d.call(this)[u](!0)
  1764. }, sfixed64: function () {
  1765. return d.call(this)[u](!1)
  1766. }
  1767. })
  1768. }
  1769. }, {15: 15}], 10: [function (p, w) {
  1770. function h(e) {
  1771. m.call(this, e)
  1772. }
  1773.  
  1774. w.exports = h;
  1775. var m = p(9);
  1776. (h.prototype = Object.create(m.prototype)).constructor = h;
  1777. var n = p(15);
  1778. n.Buffer && (h.prototype.i = n.Buffer.prototype.slice);
  1779. h.prototype.string = function () {
  1780. var e =
  1781. this.uint32();
  1782. return this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + e, this.len))
  1783. }
  1784. }, {15: 15, 9: 9}], 11: [function (p, w) {
  1785. w.exports = {}
  1786. }, {}], 12: [function (p, w, h) {
  1787. h.Service = p(13)
  1788. }, {13: 13}], 13: [function (p, w) {
  1789. function h(n, e, d) {
  1790. if ("function" != typeof n) throw TypeError("rpcImpl must be a function");
  1791. m.EventEmitter.call(this);
  1792. this.rpcImpl = n;
  1793. this.requestDelimited = !!e;
  1794. this.responseDelimited = !!d
  1795. }
  1796.  
  1797. w.exports = h;
  1798. var m = p(15);
  1799. ((h.prototype = Object.create(m.EventEmitter.prototype)).constructor = h).prototype.rpcCall = function k(e,
  1800. d, a, b, c) {
  1801. if (!b) throw TypeError("request must be specified");
  1802. var l = this;
  1803. if (!c) return m.asPromise(k, l, e, d, a, b);
  1804. if (!l.rpcImpl) return setTimeout(function () {
  1805. c(Error("already ended"))
  1806. }, 0), z;
  1807. try {
  1808. return l.rpcImpl(e, d[l.requestDelimited ? "encodeDelimited" : "encode"](b).finish(), function (q, f) {
  1809. if (q) return l.emit("error", q, e), c(q);
  1810. if (null === f) return l.end(!0), z;
  1811. if (!(f instanceof a)) try {
  1812. f = a[l.responseDelimited ? "decodeDelimited" : "decode"](f)
  1813. } catch (u) {
  1814. return l.emit("error", u, e), c(u)
  1815. }
  1816. return l.emit("data", f, e), c(null,
  1817. f)
  1818. })
  1819. } catch (q) {
  1820. return l.emit("error", q, e), setTimeout(function () {
  1821. c(q)
  1822. }, 0), z
  1823. }
  1824. };
  1825. h.prototype.end = function (e) {
  1826. return this.rpcImpl && (e || this.rpcImpl(null, null, null), this.rpcImpl = null, this.emit("end").off()), this
  1827. }
  1828. }, {15: 15}], 14: [function (p, w) {
  1829. function h(a, b) {
  1830. this.lo = a >>> 0;
  1831. this.hi = b >>> 0
  1832. }
  1833.  
  1834. w.exports = h;
  1835. var m = p(15), n = h.zero = new h(0, 0);
  1836. n.toNumber = function () {
  1837. return 0
  1838. };
  1839. n.zzEncode = n.zzDecode = function () {
  1840. return this
  1841. };
  1842. n.length = function () {
  1843. return 1
  1844. };
  1845. var e = h.zeroHash = "\x00\x00\x00\x00\x00\x00\x00\x00";
  1846. h.fromNumber = function (a) {
  1847. if (0 ===
  1848. a) return n;
  1849. var b = 0 > a;
  1850. b && (a = -a);
  1851. var c = a >>> 0;
  1852. a = (a - c) / 4294967296 >>> 0;
  1853. return b && (a = ~a >>> 0, c = ~c >>> 0, 4294967295 < ++c && (c = 0, 4294967295 < ++a && (a = 0))), new h(c, a)
  1854. };
  1855. h.from = function (a) {
  1856. if ("number" == typeof a) return h.fromNumber(a);
  1857. if (m.isString(a)) {
  1858. if (!m.Long) return h.fromNumber(parseInt(a, 10));
  1859. a = m.Long.fromString(a)
  1860. }
  1861. return a.low || a.high ? new h(a.low >>> 0, a.high >>> 0) : n
  1862. };
  1863. h.prototype.toNumber = function (a) {
  1864. if (!a && this.hi >>> 31) {
  1865. a = 1 + ~this.lo >>> 0;
  1866. var b = ~this.hi >>> 0;
  1867. return a || (b = b + 1 >>> 0), -(a + 4294967296 * b)
  1868. }
  1869. return this.lo +
  1870. 4294967296 * this.hi
  1871. };
  1872. h.prototype.toLong = function (a) {
  1873. return m.Long ? new m.Long(0 | this.lo, 0 | this.hi, !!a) : {
  1874. low: 0 | this.lo,
  1875. high: 0 | this.hi,
  1876. unsigned: !!a
  1877. }
  1878. };
  1879. var d = String.prototype.charCodeAt;
  1880. h.fromHash = function (a) {
  1881. return a === e ? n : new h((d.call(a, 0) | d.call(a, 1) << 8 | d.call(a, 2) << 16 | d.call(a, 3) << 24) >>> 0, (d.call(a, 4) | d.call(a, 5) << 8 | d.call(a, 6) << 16 | d.call(a, 7) << 24) >>> 0)
  1882. };
  1883. h.prototype.toHash = function () {
  1884. return String.fromCharCode(255 & this.lo, this.lo >>> 8 & 255, this.lo >>> 16 & 255, this.lo >>> 24, 255 & this.hi, this.hi >>> 8 & 255, this.hi >>>
  1885. 16 & 255, this.hi >>> 24)
  1886. };
  1887. h.prototype.zzEncode = function () {
  1888. var a = this.hi >> 31;
  1889. return this.hi = ((this.hi << 1 | this.lo >>> 31) ^ a) >>> 0, this.lo = (this.lo << 1 ^ a) >>> 0, this
  1890. };
  1891. h.prototype.zzDecode = function () {
  1892. var a = -(1 & this.lo);
  1893. return this.lo = ((this.lo >>> 1 | this.hi << 31) ^ a) >>> 0, this.hi = (this.hi >>> 1 ^ a) >>> 0, this
  1894. };
  1895. h.prototype.length = function () {
  1896. var a = this.lo, b = (this.lo >>> 28 | this.hi << 4) >>> 0, c = this.hi >>> 24;
  1897. return 0 === c ? 0 === b ? 16384 > a ? 128 > a ? 1 : 2 : 2097152 > a ? 3 : 4 : 16384 > b ? 128 > b ? 5 : 6 : 2097152 > b ? 7 : 8 : 128 > c ? 9 : 10
  1898. }
  1899. }, {15: 15}], 15: [function (p, w,
  1900. h) {
  1901. function m(e, d, a) {
  1902. for (var b = Object.keys(d), c = 0; c < b.length; ++c) e[b[c]] !== z && a || (e[b[c]] = d[b[c]]);
  1903. return e
  1904. }
  1905.  
  1906. function n(e) {
  1907. function d(a, b) {
  1908. if (!(this instanceof d)) return new d(a, b);
  1909. Object.defineProperty(this, "message", {
  1910. get: function () {
  1911. return a
  1912. }
  1913. });
  1914. Error.captureStackTrace ? Error.captureStackTrace(this, d) : Object.defineProperty(this, "stack", {value: Error().stack || ""});
  1915. b && m(this, b)
  1916. }
  1917.  
  1918. return (d.prototype = Object.create(Error.prototype)).constructor = d, Object.defineProperty(d.prototype, "name", {
  1919. get: function () {
  1920. return e
  1921. }
  1922. }),
  1923. d.prototype.toString = function () {
  1924. return this.name + ": " + this.message
  1925. }, d
  1926. }
  1927.  
  1928. h.asPromise = p(1);
  1929. h.base64 = p(2);
  1930. h.EventEmitter = p(3);
  1931. h["float"] = p(4);
  1932. h.inquire = p(5);
  1933. h.utf8 = p(7);
  1934. h.pool = p(6);
  1935. h.LongBits = p(14);
  1936. h.global = "undefined" != typeof window && window || "undefined" != typeof global && global || "undefined" != typeof self && self || this;
  1937. h.emptyArray = Object.freeze ? Object.freeze([]) : [];
  1938. h.emptyObject = Object.freeze ? Object.freeze({}) : {};
  1939. h.isNode = !!(h.global.process && h.global.process.versions && h.global.process.versions.node);
  1940. h.isInteger =
  1941. Number.isInteger || function (e) {
  1942. return "number" == typeof e && isFinite(e) && Math.floor(e) === e
  1943. };
  1944. h.isString = function (e) {
  1945. return "string" == typeof e || e instanceof String
  1946. };
  1947. h.isObject = function (e) {
  1948. return e && "object" == typeof e
  1949. };
  1950. h.isset = h.isSet = function (e, d) {
  1951. var a = e[d];
  1952. return !(null == a || !e.hasOwnProperty(d)) && ("object" != typeof a || 0 < (Array.isArray(a) ? a.length : Object.keys(a).length))
  1953. };
  1954. h.Buffer = function () {
  1955. try {
  1956. var e = h.inquire("buffer").Buffer;
  1957. return e.prototype.utf8Write ? e : null
  1958. } catch (d) {
  1959. return null
  1960. }
  1961. }();
  1962. h.r = null;
  1963. h.u = null;
  1964. h.newBuffer = function (e) {
  1965. return "number" == typeof e ? h.Buffer ? h.u(e) : new h.Array(e) : h.Buffer ? h.r(e) : "undefined" == typeof Uint8Array ? e : new Uint8Array(e)
  1966. };
  1967. h.Array = "undefined" != typeof Uint8Array ? Uint8Array : Array;
  1968. h.Long = h.global.dcodeIO && h.global.dcodeIO.Long || h.global.Long || h.inquire("long");
  1969. h.key2Re = /^true|false|0|1$/;
  1970. h.key32Re = /^-?(?:0|[1-9][0-9]*)$/;
  1971. h.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;
  1972. h.longToHash = function (e) {
  1973. return e ? h.LongBits.from(e).toHash() : h.LongBits.zeroHash
  1974. };
  1975. h.longFromHash = function (e,
  1976. d) {
  1977. var a = h.LongBits.fromHash(e);
  1978. return h.Long ? h.Long.fromBits(a.lo, a.hi, d) : a.toNumber(!!d)
  1979. };
  1980. h.merge = m;
  1981. h.lcFirst = function (e) {
  1982. return e.charAt(0).toLowerCase() + e.substring(1)
  1983. };
  1984. h.newError = n;
  1985. h.ProtocolError = n("ProtocolError");
  1986. h.oneOfGetter = function (e) {
  1987. for (var d = {}, a = 0; a < e.length; ++a) d[e[a]] = 1;
  1988. return function () {
  1989. for (var b = Object.keys(this), c = b.length - 1; -1 < c; --c) if (1 === d[b[c]] && this[b[c]] !== z && null !== this[b[c]]) return b[c]
  1990. }
  1991. };
  1992. h.oneOfSetter = function (e) {
  1993. return function (d) {
  1994. for (var a = 0; a < e.length; ++a) e[a] !== d &&
  1995. delete this[e[a]]
  1996. }
  1997. };
  1998. h.toJSONOptions = {longs: String, enums: String, bytes: String, json: !0};
  1999. h.n = function () {
  2000. var e = h.Buffer;
  2001. e ? (h.r = e.from !== Uint8Array.from && e.from || function (d, a) {
  2002. return new e(d, a)
  2003. }, h.u = e.allocUnsafe || function (d) {
  2004. return new e(d)
  2005. }) : h.r = h.u = null
  2006. }
  2007. }, {1: 1, 14: 14, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}], 16: [function (p, w) {
  2008. function h(g, t, x) {
  2009. this.fn = g;
  2010. this.len = t;
  2011. this.next = z;
  2012. this.val = x
  2013. }
  2014.  
  2015. function m() {
  2016. }
  2017.  
  2018. function n(g) {
  2019. this.head = g.head;
  2020. this.tail = g.tail;
  2021. this.len = g.len;
  2022. this.next = g.states
  2023. }
  2024.  
  2025. function e() {
  2026. this.len = 0;
  2027. this.tail = this.head =
  2028. new h(m, 0, 0);
  2029. this.states = null
  2030. }
  2031.  
  2032. function d(g, t, x) {
  2033. t[x] = 255 & g
  2034. }
  2035.  
  2036. function a(g, t) {
  2037. this.len = g;
  2038. this.next = z;
  2039. this.val = t
  2040. }
  2041.  
  2042. function b(g, t, x) {
  2043. for (; g.hi;) t[x++] = 127 & g.lo | 128, g.lo = (g.lo >>> 7 | g.hi << 25) >>> 0, g.hi >>>= 7;
  2044. for (; 127 < g.lo;) t[x++] = 127 & g.lo | 128, g.lo >>>= 7;
  2045. t[x++] = g.lo
  2046. }
  2047.  
  2048. function c(g, t, x) {
  2049. t[x] = 255 & g;
  2050. t[x + 1] = g >>> 8 & 255;
  2051. t[x + 2] = g >>> 16 & 255;
  2052. t[x + 3] = g >>> 24
  2053. }
  2054.  
  2055. w.exports = e;
  2056. var k, l = p(15), q = l.LongBits, f = l.base64, u = l.utf8;
  2057. e.create = l.Buffer ? function () {
  2058. return (e.create = function () {
  2059. return new k
  2060. })()
  2061. } : function () {
  2062. return new e
  2063. };
  2064. e.alloc = function (g) {
  2065. return new l.Array(g)
  2066. };
  2067. l.Array !== Array && (e.alloc = l.pool(e.alloc, l.Array.prototype.subarray));
  2068. e.prototype.e = function (g, t, x) {
  2069. return this.tail = this.tail.next = new h(g, t, x), this.len += t, this
  2070. };
  2071. (a.prototype = Object.create(h.prototype)).fn = function (g, t, x) {
  2072. for (; 127 < g;) t[x++] = 127 & g | 128, g >>>= 7;
  2073. t[x] = g
  2074. };
  2075. e.prototype.uint32 = function (g) {
  2076. return this.len += (this.tail = this.tail.next = new a(128 > (g >>>= 0) ? 1 : 16384 > g ? 2 : 2097152 > g ? 3 : 268435456 > g ? 4 : 5, g)).len, this
  2077. };
  2078. e.prototype.int32 = function (g) {
  2079. return 0 > g ? this.e(b, 10, q.fromNumber(g)) : this.uint32(g)
  2080. };
  2081. e.prototype.sint32 =
  2082. function (g) {
  2083. return this.uint32((g << 1 ^ g >> 31) >>> 0)
  2084. };
  2085. e.prototype.int64 = e.prototype.uint64 = function (g) {
  2086. g = q.from(g);
  2087. return this.e(b, g.length(), g)
  2088. };
  2089. e.prototype.sint64 = function (g) {
  2090. g = q.from(g).zzEncode();
  2091. return this.e(b, g.length(), g)
  2092. };
  2093. e.prototype.bool = function (g) {
  2094. return this.e(d, 1, g ? 1 : 0)
  2095. };
  2096. e.prototype.sfixed32 = e.prototype.fixed32 = function (g) {
  2097. return this.e(c, 4, g >>> 0)
  2098. };
  2099. e.prototype.sfixed64 = e.prototype.fixed64 = function (g) {
  2100. g = q.from(g);
  2101. return this.e(c, 4, g.lo).e(c, 4, g.hi)
  2102. };
  2103. e.prototype["float"] = function (g) {
  2104. return this.e(l["float"].writeFloatLE,
  2105. 4, g)
  2106. };
  2107. e.prototype["double"] = function (g) {
  2108. return this.e(l["float"].writeDoubleLE, 8, g)
  2109. };
  2110. var v = l.Array.prototype.set ? function (g, t, x) {
  2111. t.set(g, x)
  2112. } : function (g, t, x) {
  2113. for (var B = 0; B < g.length; ++B) t[x + B] = g[B]
  2114. };
  2115. e.prototype.bytes = function (g) {
  2116. var t = g.length >>> 0;
  2117. if (!t) return this.e(d, 1, 0);
  2118. if (l.isString(g)) {
  2119. var x = e.alloc(t = f.length(g));
  2120. f.decode(g, x, 0);
  2121. g = x
  2122. }
  2123. return this.uint32(t).e(v, t, g)
  2124. };
  2125. e.prototype.string = function (g) {
  2126. var t = u.length(g);
  2127. return t ? this.uint32(t).e(u.write, t, g) : this.e(d, 1, 0)
  2128. };
  2129. e.prototype.fork = function () {
  2130. return this.states =
  2131. new n(this), this.head = this.tail = new h(m, 0, 0), this.len = 0, this
  2132. };
  2133. e.prototype.reset = function () {
  2134. return this.states ? (this.head = this.states.head, this.tail = this.states.tail, this.len = this.states.len, this.states = this.states.next) : (this.head = this.tail = new h(m, 0, 0), this.len = 0), this
  2135. };
  2136. e.prototype.ldelim = function () {
  2137. var g = this.head, t = this.tail, x = this.len;
  2138. return this.reset().uint32(x), x && (this.tail.next = g.next, this.tail = t, this.len += x), this
  2139. };
  2140. e.prototype.finish = function () {
  2141. for (var g = this.head.next, t = this.constructor.alloc(this.len),
  2142. x = 0; g;) g.fn(g.val, t, x), x += g.len, g = g.next;
  2143. return t
  2144. };
  2145. e.n = function (g) {
  2146. k = g
  2147. }
  2148. }, {15: 15}], 17: [function (p, w) {
  2149. function h() {
  2150. n.call(this)
  2151. }
  2152.  
  2153. function m(b, c, k) {
  2154. 40 > b.length ? e.utf8.write(b, c, k) : c.utf8Write(b, k)
  2155. }
  2156.  
  2157. w.exports = h;
  2158. var n = p(16);
  2159. (h.prototype = Object.create(n.prototype)).constructor = h;
  2160. var e = p(15), d = e.Buffer;
  2161. h.alloc = function (b) {
  2162. return (h.alloc = e.u)(b)
  2163. };
  2164. var a = d && d.prototype instanceof Uint8Array && "set" === d.prototype.set.name ? function (b, c, k) {
  2165. c.set(b, k)
  2166. } : function (b, c, k) {
  2167. if (b.copy) b.copy(c, k, 0, b.length); else for (var l =
  2168. 0; l < b.length;) c[k++] = b[l++]
  2169. };
  2170. h.prototype.bytes = function (b) {
  2171. e.isString(b) && (b = e.r(b, "base64"));
  2172. var c = b.length >>> 0;
  2173. return this.uint32(c), c && this.e(a, c, b), this
  2174. };
  2175. h.prototype.string = function (b) {
  2176. var c = d.byteLength(b);
  2177. return this.uint32(c), c && this.e(m, c, b), this
  2178. }
  2179. }, {15: 15, 16: 16}]
  2180. };
  2181. var A = {};
  2182. var r = function h(w) {
  2183. var m = A[w];
  2184. return m || y[w][0].call(m = A[w] = {exports: {}}, h, m, m.exports), m.exports
  2185. }(8);
  2186. r.util.global.protobuf = r;
  2187. "function" == typeof define && define.amd && define(["long"], function (w) {
  2188. return w && w.isLong && (r.util.Long =
  2189. w, r.configure()), r
  2190. });
  2191. "object" == typeof module && module && module.exports && (module.exports = r)
  2192. }();
  2193. (function (z) {
  2194. var y = z.Reader, A = z.Writer, r = z.util, p = z.roots["default"] || (z.roots["default"] = {});
  2195. p.bilibili = function () {
  2196. var w = {};
  2197. w.community = function () {
  2198. var h = {};
  2199. h.service = function () {
  2200. var m = {};
  2201. m.dm = function () {
  2202. var n = {};
  2203. n.v1 = function () {
  2204. var e = {};
  2205. e.DmWebViewReply = function () {
  2206. function d(a) {
  2207. this.specialDms = [];
  2208. if (a) for (var b = Object.keys(a), c = 0; c < b.length; ++c) null != a[b[c]] && (this[b[c]] = a[b[c]])
  2209. }
  2210.  
  2211. d.prototype.state = 0;
  2212. d.prototype.text = "";
  2213. d.prototype.textSide = "";
  2214. d.prototype.dmSge = null;
  2215. d.prototype.flag = null;
  2216. d.prototype.specialDms =
  2217. r.emptyArray;
  2218. d.create = function (a) {
  2219. return new d(a)
  2220. };
  2221. d.encode = function (a, b) {
  2222. b || (b = A.create());
  2223. null != a.state && Object.hasOwnProperty.call(a, "state") && b.uint32(8).int32(a.state);
  2224. null != a.text && Object.hasOwnProperty.call(a, "text") && b.uint32(18).string(a.text);
  2225. null != a.textSide && Object.hasOwnProperty.call(a, "textSide") && b.uint32(26).string(a.textSide);
  2226. null != a.dmSge && Object.hasOwnProperty.call(a, "dmSge") && p.bilibili.community.service.dm.v1.DmSegConfig.encode(a.dmSge, b.uint32(34).fork()).ldelim();
  2227. null != a.flag &&
  2228. Object.hasOwnProperty.call(a, "flag") && p.bilibili.community.service.dm.v1.DanmakuFlagConfig.encode(a.flag, b.uint32(42).fork()).ldelim();
  2229. if (null != a.specialDms && a.specialDms.length) for (var c = 0; c < a.specialDms.length; ++c) b.uint32(50).string(a.specialDms[c]);
  2230. return b
  2231. };
  2232. d.encodeDelimited = function (a, b) {
  2233. return this.encode(a, b).ldelim()
  2234. };
  2235. d.decode = function (a, b) {
  2236. a instanceof y || (a = y.create(a));
  2237. for (var c = void 0 === b ? a.len : a.pos + b, k = new p.bilibili.community.service.dm.v1.DmWebViewReply; a.pos < c;) {
  2238. var l = a.uint32();
  2239. switch (l >>> 3) {
  2240. case 1:
  2241. k.state = a.int32();
  2242. break;
  2243. case 2:
  2244. k.text = a.string();
  2245. break;
  2246. case 3:
  2247. k.textSide = a.string();
  2248. break;
  2249. case 4:
  2250. k.dmSge = p.bilibili.community.service.dm.v1.DmSegConfig.decode(a, a.uint32());
  2251. break;
  2252. case 5:
  2253. k.flag = p.bilibili.community.service.dm.v1.DanmakuFlagConfig.decode(a, a.uint32());
  2254. break;
  2255. case 6:
  2256. k.specialDms && k.specialDms.length || (k.specialDms = []);
  2257. k.specialDms.push(a.string());
  2258. break;
  2259. default:
  2260. a.skipType(l & 7)
  2261. }
  2262. }
  2263. return k
  2264. };
  2265. d.decodeDelimited = function (a) {
  2266. a instanceof y || (a = new y(a));
  2267. return this.decode(a,
  2268. a.uint32())
  2269. };
  2270. d.verify = function (a) {
  2271. if ("object" !== typeof a || null === a) return "object expected";
  2272. if (null != a.state && a.hasOwnProperty("state") && !r.isInteger(a.state)) return "state: integer expected";
  2273. if (null != a.text && a.hasOwnProperty("text") && !r.isString(a.text)) return "text: string expected";
  2274. if (null != a.textSide && a.hasOwnProperty("textSide") && !r.isString(a.textSide)) return "textSide: string expected";
  2275. if (null != a.dmSge && a.hasOwnProperty("dmSge")) {
  2276. var b = p.bilibili.community.service.dm.v1.DmSegConfig.verify(a.dmSge);
  2277. if (b) return "dmSge." + b
  2278. }
  2279. if (null != a.flag && a.hasOwnProperty("flag") && (b = p.bilibili.community.service.dm.v1.DanmakuFlagConfig.verify(a.flag))) return "flag." + b;
  2280. if (null != a.specialDms && a.hasOwnProperty("specialDms")) {
  2281. if (!Array.isArray(a.specialDms)) return "specialDms: array expected";
  2282. for (b = 0; b < a.specialDms.length; ++b) if (!r.isString(a.specialDms[b])) return "specialDms: string[] expected"
  2283. }
  2284. return null
  2285. };
  2286. d.fromObject = function (a) {
  2287. if (a instanceof p.bilibili.community.service.dm.v1.DmWebViewReply) return a;
  2288. var b = new p.bilibili.community.service.dm.v1.DmWebViewReply;
  2289. null != a.state && (b.state = a.state | 0);
  2290. null != a.text && (b.text = String(a.text));
  2291. null != a.textSide && (b.textSide = String(a.textSide));
  2292. if (null != a.dmSge) {
  2293. if ("object" !== typeof a.dmSge) throw TypeError(".bilibili.community.service.dm.v1.DmWebViewReply.dmSge: object expected");
  2294. b.dmSge = p.bilibili.community.service.dm.v1.DmSegConfig.fromObject(a.dmSge)
  2295. }
  2296. if (null != a.flag) {
  2297. if ("object" !== typeof a.flag) throw TypeError(".bilibili.community.service.dm.v1.DmWebViewReply.flag: object expected");
  2298. b.flag = p.bilibili.community.service.dm.v1.DanmakuFlagConfig.fromObject(a.flag)
  2299. }
  2300. if (a.specialDms) {
  2301. if (!Array.isArray(a.specialDms)) throw TypeError(".bilibili.community.service.dm.v1.DmWebViewReply.specialDms: array expected");
  2302. b.specialDms = [];
  2303. for (var c = 0; c < a.specialDms.length; ++c) b.specialDms[c] = String(a.specialDms[c])
  2304. }
  2305. return b
  2306. };
  2307. d.toObject = function (a, b) {
  2308. b || (b = {});
  2309. var c = {};
  2310. if (b.arrays || b.defaults) c.specialDms = [];
  2311. b.defaults && (c.state = 0, c.text = "", c.textSide = "", c.dmSge = null, c.flag = null);
  2312. null != a.state && a.hasOwnProperty("state") && (c.state = a.state);
  2313. null != a.text && a.hasOwnProperty("text") && (c.text = a.text);
  2314. null != a.textSide && a.hasOwnProperty("textSide") && (c.textSide = a.textSide);
  2315. null != a.dmSge && a.hasOwnProperty("dmSge") && (c.dmSge = p.bilibili.community.service.dm.v1.DmSegConfig.toObject(a.dmSge,
  2316. b));
  2317. null != a.flag && a.hasOwnProperty("flag") && (c.flag = p.bilibili.community.service.dm.v1.DanmakuFlagConfig.toObject(a.flag, b));
  2318. if (a.specialDms && a.specialDms.length) {
  2319. c.specialDms = [];
  2320. for (var k = 0; k < a.specialDms.length; ++k) c.specialDms[k] = a.specialDms[k]
  2321. }
  2322. return c
  2323. };
  2324. d.prototype.toJSON = function () {
  2325. return this.constructor.toObject(this, z.util.toJSONOptions)
  2326. };
  2327. return d
  2328. }();
  2329. e.DmSegConfig = function () {
  2330. function d(a) {
  2331. if (a) for (var b = Object.keys(a), c = 0; c < b.length; ++c) null != a[b[c]] && (this[b[c]] = a[b[c]])
  2332. }
  2333.  
  2334. d.prototype.pageSize =
  2335. r.Long ? r.Long.fromBits(0, 0, !1) : 0;
  2336. d.prototype.total = r.Long ? r.Long.fromBits(0, 0, !1) : 0;
  2337. d.create = function (a) {
  2338. return new d(a)
  2339. };
  2340. d.encode = function (a, b) {
  2341. b || (b = A.create());
  2342. null != a.pageSize && Object.hasOwnProperty.call(a, "pageSize") && b.uint32(8).int64(a.pageSize);
  2343. null != a.total && Object.hasOwnProperty.call(a, "total") && b.uint32(16).int64(a.total);
  2344. return b
  2345. };
  2346. d.encodeDelimited = function (a, b) {
  2347. return this.encode(a, b).ldelim()
  2348. };
  2349. d.decode = function (a, b) {
  2350. a instanceof y || (a = y.create(a));
  2351. for (var c = void 0 === b ? a.len : a.pos + b,
  2352. k = new p.bilibili.community.service.dm.v1.DmSegConfig; a.pos < c;) {
  2353. var l = a.uint32();
  2354. switch (l >>> 3) {
  2355. case 1:
  2356. k.pageSize = a.int64();
  2357. break;
  2358. case 2:
  2359. k.total = a.int64();
  2360. break;
  2361. default:
  2362. a.skipType(l & 7)
  2363. }
  2364. }
  2365. return k
  2366. };
  2367. d.decodeDelimited = function (a) {
  2368. a instanceof y || (a = new y(a));
  2369. return this.decode(a, a.uint32())
  2370. };
  2371. d.verify = function (a) {
  2372. return "object" !== typeof a || null === a ? "object expected" : null == a.pageSize || !a.hasOwnProperty("pageSize") || r.isInteger(a.pageSize) || a.pageSize && r.isInteger(a.pageSize.low) && r.isInteger(a.pageSize.high) ?
  2373. null == a.total || !a.hasOwnProperty("total") || r.isInteger(a.total) || a.total && r.isInteger(a.total.low) && r.isInteger(a.total.high) ? null : "total: integer|Long expected" : "pageSize: integer|Long expected"
  2374. };
  2375. d.fromObject = function (a) {
  2376. if (a instanceof p.bilibili.community.service.dm.v1.DmSegConfig) return a;
  2377. var b = new p.bilibili.community.service.dm.v1.DmSegConfig;
  2378. null != a.pageSize && (r.Long ? (b.pageSize = r.Long.fromValue(a.pageSize)).unsigned = !1 : "string" === typeof a.pageSize ? b.pageSize = parseInt(a.pageSize, 10) : "number" ===
  2379. typeof a.pageSize ? b.pageSize = a.pageSize : "object" === typeof a.pageSize && (b.pageSize = (new r.LongBits(a.pageSize.low >>> 0, a.pageSize.high >>> 0)).toNumber()));
  2380. null != a.total && (r.Long ? (b.total = r.Long.fromValue(a.total)).unsigned = !1 : "string" === typeof a.total ? b.total = parseInt(a.total, 10) : "number" === typeof a.total ? b.total = a.total : "object" === typeof a.total && (b.total = (new r.LongBits(a.total.low >>> 0, a.total.high >>> 0)).toNumber()));
  2381. return b
  2382. };
  2383. d.toObject = function (a, b) {
  2384. b || (b = {});
  2385. var c = {};
  2386. if (b.defaults) {
  2387. if (r.Long) {
  2388. var k =
  2389. new r.Long(0, 0, !1);
  2390. c.pageSize = b.longs === String ? k.toString() : b.longs === Number ? k.toNumber() : k
  2391. } else c.pageSize = b.longs === String ? "0" : 0;
  2392. r.Long ? (k = new r.Long(0, 0, !1), c.total = b.longs === String ? k.toString() : b.longs === Number ? k.toNumber() : k) : c.total = b.longs === String ? "0" : 0
  2393. }
  2394. null != a.pageSize && a.hasOwnProperty("pageSize") && (c.pageSize = "number" === typeof a.pageSize ? b.longs === String ? String(a.pageSize) : a.pageSize : b.longs === String ? r.Long.prototype.toString.call(a.pageSize) : b.longs === Number ? (new r.LongBits(a.pageSize.low >>>
  2395. 0, a.pageSize.high >>> 0)).toNumber() : a.pageSize);
  2396. null != a.total && a.hasOwnProperty("total") && (c.total = "number" === typeof a.total ? b.longs === String ? String(a.total) : a.total : b.longs === String ? r.Long.prototype.toString.call(a.total) : b.longs === Number ? (new r.LongBits(a.total.low >>> 0, a.total.high >>> 0)).toNumber() : a.total);
  2397. return c
  2398. };
  2399. d.prototype.toJSON = function () {
  2400. return this.constructor.toObject(this, z.util.toJSONOptions)
  2401. };
  2402. return d
  2403. }();
  2404. e.DanmakuFlagConfig = function () {
  2405. function d(a) {
  2406. if (a) for (var b = Object.keys(a), c = 0; c <
  2407. b.length; ++c) null != a[b[c]] && (this[b[c]] = a[b[c]])
  2408. }
  2409.  
  2410. d.prototype.recFlag = 0;
  2411. d.prototype.recText = "";
  2412. d.prototype.recSwitch = 0;
  2413. d.create = function (a) {
  2414. return new d(a)
  2415. };
  2416. d.encode = function (a, b) {
  2417. b || (b = A.create());
  2418. null != a.recFlag && Object.hasOwnProperty.call(a, "recFlag") && b.uint32(8).int32(a.recFlag);
  2419. null != a.recText && Object.hasOwnProperty.call(a, "recText") && b.uint32(18).string(a.recText);
  2420. null != a.recSwitch && Object.hasOwnProperty.call(a, "recSwitch") && b.uint32(24).int32(a.recSwitch);
  2421. return b
  2422. };
  2423. d.encodeDelimited = function (a,
  2424. b) {
  2425. return this.encode(a, b).ldelim()
  2426. };
  2427. d.decode = function (a, b) {
  2428. a instanceof y || (a = y.create(a));
  2429. for (var c = void 0 === b ? a.len : a.pos + b, k = new p.bilibili.community.service.dm.v1.DanmakuFlagConfig; a.pos < c;) {
  2430. var l = a.uint32();
  2431. switch (l >>> 3) {
  2432. case 1:
  2433. k.recFlag = a.int32();
  2434. break;
  2435. case 2:
  2436. k.recText = a.string();
  2437. break;
  2438. case 3:
  2439. k.recSwitch = a.int32();
  2440. break;
  2441. default:
  2442. a.skipType(l & 7)
  2443. }
  2444. }
  2445. return k
  2446. };
  2447. d.decodeDelimited = function (a) {
  2448. a instanceof y || (a = new y(a));
  2449. return this.decode(a, a.uint32())
  2450. };
  2451. d.verify = function (a) {
  2452. return "object" !== typeof a ||
  2453. null === a ? "object expected" : null != a.recFlag && a.hasOwnProperty("recFlag") && !r.isInteger(a.recFlag) ? "recFlag: integer expected" : null != a.recText && a.hasOwnProperty("recText") && !r.isString(a.recText) ? "recText: string expected" : null != a.recSwitch && a.hasOwnProperty("recSwitch") && !r.isInteger(a.recSwitch) ? "recSwitch: integer expected" : null
  2454. };
  2455. d.fromObject = function (a) {
  2456. if (a instanceof p.bilibili.community.service.dm.v1.DanmakuFlagConfig) return a;
  2457. var b = new p.bilibili.community.service.dm.v1.DanmakuFlagConfig;
  2458. null !=
  2459. a.recFlag && (b.recFlag = a.recFlag | 0);
  2460. null != a.recText && (b.recText = String(a.recText));
  2461. null != a.recSwitch && (b.recSwitch = a.recSwitch | 0);
  2462. return b
  2463. };
  2464. d.toObject = function (a, b) {
  2465. b || (b = {});
  2466. var c = {};
  2467. b.defaults && (c.recFlag = 0, c.recText = "", c.recSwitch = 0);
  2468. null != a.recFlag && a.hasOwnProperty("recFlag") && (c.recFlag = a.recFlag);
  2469. null != a.recText && a.hasOwnProperty("recText") && (c.recText = a.recText);
  2470. null != a.recSwitch && a.hasOwnProperty("recSwitch") && (c.recSwitch = a.recSwitch);
  2471. return c
  2472. };
  2473. d.prototype.toJSON = function () {
  2474. return this.constructor.toObject(this,
  2475. z.util.toJSONOptions)
  2476. };
  2477. return d
  2478. }();
  2479. e.DmSegMobileReply = function () {
  2480. function d(a) {
  2481. this.elems = [];
  2482. if (a) for (var b = Object.keys(a), c = 0; c < b.length; ++c) null != a[b[c]] && (this[b[c]] = a[b[c]])
  2483. }
  2484.  
  2485. d.prototype.elems = r.emptyArray;
  2486. d.create = function (a) {
  2487. return new d(a)
  2488. };
  2489. d.encode = function (a, b) {
  2490. b || (b = A.create());
  2491. if (null != a.elems && a.elems.length) for (var c = 0; c < a.elems.length; ++c) p.bilibili.community.service.dm.v1.DanmakuElem.encode(a.elems[c], b.uint32(10).fork()).ldelim();
  2492. return b
  2493. };
  2494. d.encodeDelimited = function (a, b) {
  2495. return this.encode(a,
  2496. b).ldelim()
  2497. };
  2498. d.decode = function (a, b) {
  2499. a instanceof y || (a = y.create(a));
  2500. for (var c = void 0 === b ? a.len : a.pos + b, k = new p.bilibili.community.service.dm.v1.DmSegMobileReply; a.pos < c;) {
  2501. var l = a.uint32();
  2502. switch (l >>> 3) {
  2503. case 1:
  2504. k.elems && k.elems.length || (k.elems = []);
  2505. k.elems.push(p.bilibili.community.service.dm.v1.DanmakuElem.decode(a, a.uint32()));
  2506. break;
  2507. default:
  2508. a.skipType(l & 7)
  2509. }
  2510. }
  2511. return k
  2512. };
  2513. d.decodeDelimited = function (a) {
  2514. a instanceof y || (a = new y(a));
  2515. return this.decode(a, a.uint32())
  2516. };
  2517. d.verify = function (a) {
  2518. if ("object" !== typeof a ||
  2519. null === a) return "object expected";
  2520. if (null != a.elems && a.hasOwnProperty("elems")) {
  2521. if (!Array.isArray(a.elems)) return "elems: array expected";
  2522. for (var b = 0; b < a.elems.length; ++b) {
  2523. var c = p.bilibili.community.service.dm.v1.DanmakuElem.verify(a.elems[b]);
  2524. if (c) return "elems." + c
  2525. }
  2526. }
  2527. return null
  2528. };
  2529. d.fromObject = function (a) {
  2530. if (a instanceof p.bilibili.community.service.dm.v1.DmSegMobileReply) return a;
  2531. var b = new p.bilibili.community.service.dm.v1.DmSegMobileReply;
  2532. if (a.elems) {
  2533. if (!Array.isArray(a.elems)) throw TypeError(".bilibili.community.service.dm.v1.DmSegMobileReply.elems: array expected");
  2534. b.elems = [];
  2535. for (var c = 0; c < a.elems.length; ++c) {
  2536. if ("object" !== typeof a.elems[c]) throw TypeError(".bilibili.community.service.dm.v1.DmSegMobileReply.elems: object expected");
  2537. b.elems[c] = p.bilibili.community.service.dm.v1.DanmakuElem.fromObject(a.elems[c])
  2538. }
  2539. }
  2540. return b
  2541. };
  2542. d.toObject = function (a, b) {
  2543. b || (b = {});
  2544. var c = {};
  2545. if (b.arrays || b.defaults) c.elems = [];
  2546. if (a.elems && a.elems.length) {
  2547. c.elems = [];
  2548. for (var k = 0; k < a.elems.length; ++k) c.elems[k] = p.bilibili.community.service.dm.v1.DanmakuElem.toObject(a.elems[k], b)
  2549. }
  2550. return c
  2551. };
  2552. d.prototype.toJSON = function () {
  2553. return this.constructor.toObject(this, z.util.toJSONOptions)
  2554. };
  2555. return d
  2556. }();
  2557. e.DanmakuElem = function () {
  2558. function d(a) {
  2559. if (a) for (var b = Object.keys(a), c = 0; c < b.length; ++c) null != a[b[c]] && (this[b[c]] = a[b[c]])
  2560. }
  2561.  
  2562. d.prototype.id = r.Long ? r.Long.fromBits(0, 0, !1) : 0;
  2563. d.prototype.progress = 0;
  2564. d.prototype.mode = 0;
  2565. d.prototype.fontsize = 0;
  2566. d.prototype.color = 0;
  2567. d.prototype.midHash = "";
  2568. d.prototype.content = "";
  2569. d.prototype.ctime = r.Long ? r.Long.fromBits(0, 0, !1) : 0;
  2570. d.prototype.weight = 0;
  2571. d.prototype.action = "";
  2572. d.prototype.pool =
  2573. 0;
  2574. d.prototype.idStr = "";
  2575. d.create = function (a) {
  2576. return new d(a)
  2577. };
  2578. d.encode = function (a, b) {
  2579. b || (b = A.create());
  2580. null != a.id && Object.hasOwnProperty.call(a, "id") && b.uint32(8).int64(a.id);
  2581. null != a.progress && Object.hasOwnProperty.call(a, "progress") && b.uint32(16).int32(a.progress);
  2582. null != a.mode && Object.hasOwnProperty.call(a, "mode") && b.uint32(24).int32(a.mode);
  2583. null != a.fontsize && Object.hasOwnProperty.call(a, "fontsize") && b.uint32(32).int32(a.fontsize);
  2584. null != a.color && Object.hasOwnProperty.call(a, "color") && b.uint32(40).uint32(a.color);
  2585. null != a.midHash && Object.hasOwnProperty.call(a, "midHash") && b.uint32(50).string(a.midHash);
  2586. null != a.content && Object.hasOwnProperty.call(a, "content") && b.uint32(58).string(a.content);
  2587. null != a.ctime && Object.hasOwnProperty.call(a, "ctime") && b.uint32(64).int64(a.ctime);
  2588. null != a.weight && Object.hasOwnProperty.call(a, "weight") && b.uint32(72).int32(a.weight);
  2589. null != a.action && Object.hasOwnProperty.call(a, "action") && b.uint32(82).string(a.action);
  2590. null != a.pool && Object.hasOwnProperty.call(a, "pool") && b.uint32(88).int32(a.pool);
  2591. null != a.idStr && Object.hasOwnProperty.call(a, "idStr") && b.uint32(98).string(a.idStr);
  2592. return b
  2593. };
  2594. d.encodeDelimited = function (a, b) {
  2595. return this.encode(a, b).ldelim()
  2596. };
  2597. d.decode = function (a, b) {
  2598. a instanceof y || (a = y.create(a));
  2599. for (var c = void 0 === b ? a.len : a.pos + b, k = new p.bilibili.community.service.dm.v1.DanmakuElem; a.pos < c;) {
  2600. var l = a.uint32();
  2601. switch (l >>> 3) {
  2602. case 1:
  2603. k.id = a.int64();
  2604. break;
  2605. case 2:
  2606. k.progress = a.int32();
  2607. break;
  2608. case 3:
  2609. k.mode = a.int32();
  2610. break;
  2611. case 4:
  2612. k.fontsize = a.int32();
  2613. break;
  2614. case 5:
  2615. k.color = a.uint32();
  2616. break;
  2617. case 6:
  2618. k.midHash = a.string();
  2619. break;
  2620. case 7:
  2621. k.content = a.string();
  2622. break;
  2623. case 8:
  2624. k.ctime = a.int64();
  2625. break;
  2626. case 9:
  2627. k.weight = a.int32();
  2628. break;
  2629. case 10:
  2630. k.action = a.string();
  2631. break;
  2632. case 11:
  2633. k.pool = a.int32();
  2634. break;
  2635. case 12:
  2636. k.idStr = a.string();
  2637. break;
  2638. default:
  2639. a.skipType(l & 7)
  2640. }
  2641. }
  2642. return k
  2643. };
  2644. d.decodeDelimited = function (a) {
  2645. a instanceof y || (a = new y(a));
  2646. return this.decode(a, a.uint32())
  2647. };
  2648. d.verify = function (a) {
  2649. return "object" !== typeof a || null === a ? "object expected" : null == a.id || !a.hasOwnProperty("id") || r.isInteger(a.id) || a.id && r.isInteger(a.id.low) &&
  2650. r.isInteger(a.id.high) ? null != a.progress && a.hasOwnProperty("progress") && !r.isInteger(a.progress) ? "progress: integer expected" : null != a.mode && a.hasOwnProperty("mode") && !r.isInteger(a.mode) ? "mode: integer expected" : null != a.fontsize && a.hasOwnProperty("fontsize") && !r.isInteger(a.fontsize) ? "fontsize: integer expected" : null != a.color && a.hasOwnProperty("color") && !r.isInteger(a.color) ? "color: integer expected" : null != a.midHash && a.hasOwnProperty("midHash") && !r.isString(a.midHash) ? "midHash: string expected" : null !=
  2651. a.content && a.hasOwnProperty("content") && !r.isString(a.content) ? "content: string expected" : null == a.ctime || !a.hasOwnProperty("ctime") || r.isInteger(a.ctime) || a.ctime && r.isInteger(a.ctime.low) && r.isInteger(a.ctime.high) ? null != a.weight && a.hasOwnProperty("weight") && !r.isInteger(a.weight) ? "weight: integer expected" : null != a.action && a.hasOwnProperty("action") && !r.isString(a.action) ? "action: string expected" : null != a.pool && a.hasOwnProperty("pool") && !r.isInteger(a.pool) ? "pool: integer expected" : null != a.idStr &&
  2652. a.hasOwnProperty("idStr") && !r.isString(a.idStr) ? "idStr: string expected" : null : "ctime: integer|Long expected" : "id: integer|Long expected"
  2653. };
  2654. d.fromObject = function (a) {
  2655. if (a instanceof p.bilibili.community.service.dm.v1.DanmakuElem) return a;
  2656. var b = new p.bilibili.community.service.dm.v1.DanmakuElem;
  2657. null != a.id && (r.Long ? (b.id = r.Long.fromValue(a.id)).unsigned = !1 : "string" === typeof a.id ? b.id = parseInt(a.id, 10) : "number" === typeof a.id ? b.id = a.id : "object" === typeof a.id && (b.id = (new r.LongBits(a.id.low >>> 0, a.id.high >>>
  2658. 0)).toNumber()));
  2659. null != a.progress && (b.progress = a.progress | 0);
  2660. null != a.mode && (b.mode = a.mode | 0);
  2661. null != a.fontsize && (b.fontsize = a.fontsize | 0);
  2662. null != a.color && (b.color = a.color >>> 0);
  2663. null != a.midHash && (b.midHash = String(a.midHash));
  2664. null != a.content && (b.content = String(a.content));
  2665. null != a.ctime && (r.Long ? (b.ctime = r.Long.fromValue(a.ctime)).unsigned = !1 : "string" === typeof a.ctime ? b.ctime = parseInt(a.ctime, 10) : "number" === typeof a.ctime ? b.ctime = a.ctime : "object" === typeof a.ctime && (b.ctime = (new r.LongBits(a.ctime.low >>>
  2666. 0, a.ctime.high >>> 0)).toNumber()));
  2667. null != a.weight && (b.weight = a.weight | 0);
  2668. null != a.action && (b.action = String(a.action));
  2669. null != a.pool && (b.pool = a.pool | 0);
  2670. null != a.idStr && (b.idStr = String(a.idStr));
  2671. return b
  2672. };
  2673. d.toObject = function (a, b) {
  2674. b || (b = {});
  2675. var c = {};
  2676. if (b.defaults) {
  2677. if (r.Long) {
  2678. var k = new r.Long(0, 0, !1);
  2679. c.id = b.longs === String ? k.toString() : b.longs === Number ? k.toNumber() : k
  2680. } else c.id = b.longs === String ? "0" : 0;
  2681. c.progress = 0;
  2682. c.mode = 0;
  2683. c.fontsize = 0;
  2684. c.color = 0;
  2685. c.midHash = "";
  2686. c.content = "";
  2687. r.Long ? (k = new r.Long(0, 0, !1), c.ctime =
  2688. b.longs === String ? k.toString() : b.longs === Number ? k.toNumber() : k) : c.ctime = b.longs === String ? "0" : 0;
  2689. c.weight = 0;
  2690. c.action = "";
  2691. c.pool = 0;
  2692. c.idStr = ""
  2693. }
  2694. null != a.id && a.hasOwnProperty("id") && (c.id = "number" === typeof a.id ? b.longs === String ? String(a.id) : a.id : b.longs === String ? r.Long.prototype.toString.call(a.id) : b.longs === Number ? (new r.LongBits(a.id.low >>> 0, a.id.high >>> 0)).toNumber() : a.id);
  2695. null != a.progress && a.hasOwnProperty("progress") && (c.progress = a.progress);
  2696. null != a.mode && a.hasOwnProperty("mode") && (c.mode = a.mode);
  2697. null !=
  2698. a.fontsize && a.hasOwnProperty("fontsize") && (c.fontsize = a.fontsize);
  2699. null != a.color && a.hasOwnProperty("color") && (c.color = a.color);
  2700. null != a.midHash && a.hasOwnProperty("midHash") && (c.midHash = a.midHash);
  2701. null != a.content && a.hasOwnProperty("content") && (c.content = a.content);
  2702. null != a.ctime && a.hasOwnProperty("ctime") && (c.ctime = "number" === typeof a.ctime ? b.longs === String ? String(a.ctime) : a.ctime : b.longs === String ? r.Long.prototype.toString.call(a.ctime) : b.longs === Number ? (new r.LongBits(a.ctime.low >>> 0, a.ctime.high >>>
  2703. 0)).toNumber() : a.ctime);
  2704. null != a.weight && a.hasOwnProperty("weight") && (c.weight = a.weight);
  2705. null != a.action && a.hasOwnProperty("action") && (c.action = a.action);
  2706. null != a.pool && a.hasOwnProperty("pool") && (c.pool = a.pool);
  2707. null != a.idStr && a.hasOwnProperty("idStr") && (c.idStr = a.idStr);
  2708. return c
  2709. };
  2710. d.prototype.toJSON = function () {
  2711. return this.constructor.toObject(this, z.util.toJSONOptions)
  2712. };
  2713. return d
  2714. }();
  2715. return e
  2716. }();
  2717. return n
  2718. }();
  2719. return m
  2720. }();
  2721. return h
  2722. }();
  2723. return w
  2724. }();
  2725. return p
  2726. })(protobuf);
  2727. var proto_seg = protobuf.roots["default"].bilibili.community.service.dm.v1.DmSegMobileReply;
  2728.  
  2729. function htmlEscape(text) {
  2730. if (!text) return text
  2731. text = text.replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f]/g, ' ')
  2732. return text.replace(/[<>"&]/g, function (match, pos, originalText) {
  2733. switch (match) {
  2734. case "<":
  2735. return "&lt;";
  2736. case ">":
  2737. return "&gt;";
  2738. case "&":
  2739. return "&amp;";
  2740. case "\"":
  2741. return '"';
  2742. }
  2743. });
  2744. }
  2745.  
  2746. function xmlunEscape(content) {
  2747. return content.replace(';', ';')
  2748. .replace(/&amp;/g, '&')
  2749. .replace(/&lt;/g, '<')
  2750. .replace(/&gt;/g, '>')
  2751. .replace(/&apos;/g, "'")
  2752. .replace(/&quot;/g, '"')
  2753. }
  2754.  
  2755. function xml2danmu(sdanmu, user = null) {
  2756. let ldanmu = sdanmu.split('</d><d p=');
  2757.  
  2758. if (ldanmu.length === 1) {
  2759. return []
  2760. }
  2761. let tdanmu = ldanmu[0];
  2762. ldanmu[0] = tdanmu.slice(tdanmu.indexOf('<d p=') + 5, tdanmu.length);
  2763. tdanmu = ldanmu[ldanmu.length - 1];
  2764. ldanmu[ldanmu.length - 1] = tdanmu.slice(0, tdanmu.length - 8);
  2765. for (let i = 0; i < ldanmu.length; i++) {
  2766. let danmu = ldanmu[i]
  2767. let argv = danmu.substring(1, danmu.indexOf('"', 2)).split(',')
  2768. ldanmu[i] = {
  2769. color: Number(argv[3]),
  2770. content: xmlunEscape(danmu.slice(danmu.indexOf('>') + 1, danmu.length)),
  2771. ctime: Number(argv[4]),
  2772. fontsize: Number(argv[2]),
  2773. id: Number(argv[7]),
  2774. idStr: argv[7],
  2775. midHash: argv[6],
  2776. mode: Number(argv[1]),
  2777. progress: Math.round(Number(argv[0]) * 1000),
  2778. weight: 10
  2779. }
  2780. }
  2781. return ldanmu
  2782. }
  2783.  
  2784. async function loadProtoDanmu(url, timeout = null, header = null, retry = 0) {
  2785. if (header === null) {
  2786. header = {
  2787. "referer": 'https://www.bilibili.com/bangumi/play/ep790784',
  2788. origin: 'https://www.bilibili.com',
  2789. 'sec-fetch-site': 'same-site'
  2790. }
  2791. }
  2792. while (true) {
  2793. try {
  2794. let result = await new Promise((resolve) => {
  2795. GM_xmlhttpRequest({
  2796. method: 'GET',
  2797. url: url,
  2798. responseType: 'arraybuffer',
  2799. headers: header,
  2800. timeout: timeout || 30000,
  2801. withCredentials: true,
  2802. onload: (response) => {
  2803. if (response.status === 200) {
  2804. let lpdanmu;
  2805. try {
  2806. lpdanmu = proto_seg.decode(new Uint8Array(response.response));
  2807. } catch (e) {
  2808. console.log('XhrError=', retry);
  2809. if (retry < 3) {
  2810. return resolve(loadProtoDanmu(url, timeout, header, retry + 1));
  2811. } else {
  2812. return resolve(null);
  2813. }
  2814. }
  2815. try {
  2816. lpdanmu.elems.forEach((e) => {
  2817. if (!e.progress) e.progress = 0;
  2818. });
  2819. resolve(lpdanmu.elems);
  2820. } catch (e) {
  2821. console.log(e.stack);
  2822. resolve([]);
  2823. }
  2824. } else if (response.status === 304) {
  2825. resolve([]);
  2826. } else {
  2827. console.log(response.status, response);
  2828. resolve(null);
  2829. }
  2830. },
  2831. onerror: (error) => {
  2832. console.log('XhrError=', retry);
  2833. retry += 1;
  2834. if (retry > 3) {
  2835. setTimeout(() => resolve(null), 10 * 1000);
  2836. } else {
  2837. setTimeout(() => resolve(null), retry * 2 * 1000);
  2838. }
  2839. },
  2840. });
  2841. });
  2842.  
  2843. if (result === null) {
  2844. retry += 1;
  2845. } else {
  2846. return result;
  2847. }
  2848. } catch (e) {
  2849. console.log('XhrError=', retry);
  2850. retry += 1;
  2851. }
  2852. await sleep(1000)
  2853. if (retry > 3) {
  2854. setTimeout(() => resolve(null), 10 * 1000);
  2855. } else {
  2856. setTimeout(() => resolve(null), retry * 2 * 1000);
  2857. }
  2858. }
  2859. }
  2860.  
  2861. function savedanmuStandalone(ldanmu, info = null) {
  2862. var end, head;
  2863. head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><i><chatserver>chat.bilibili.com</chatserver><chatid>0</chatid><mission>0</mission><maxlimit>0</maxlimit><state>0</state><real_name>0</real_name><source>DF</source>"
  2864. end = "</i>";
  2865. if ((info !== null)) {
  2866. head += '<info>' + htmlEscape(JSON.stringify(info)) + '</info>';
  2867. }
  2868. return head + ldanmu.join('') + end
  2869. }
  2870.  
  2871.  
  2872. function danmuObject2XML(ldanmu) {
  2873. for (let i = 0, length = ldanmu.length; i < length; i++) {
  2874. let danmu = ldanmu[i]
  2875. ldanmu[i] = `<d p="${(danmu.progress ? danmu.progress : 0) / 1000},${danmu.mode},${danmu.fontsize},${danmu.color},${danmu.ctime},${0},${danmu.midHash},${danmu.id}">${htmlEscape(danmu.content)}</d>`
  2876. }
  2877. return ldanmu
  2878. }
  2879.  
  2880.  
  2881. async function moreHistory(cid) {
  2882. let date = new Date();
  2883. if (videoPublishDate && currentSetting.capturePeriodEnd !== -1) {
  2884. date.setTime((videoPublishDate + currentSetting.capturePeriodEnd * 86400) * 1000)
  2885. } else {
  2886. date.setTime(date.getTime() - 86400000)
  2887. }
  2888. console.log('GetDanmuFor CID' + cid)
  2889. let aldanmu = [], ldanmu = []
  2890. let firstdate = 0;
  2891. let ndanmu, ondanmu
  2892. let url = 'https://comment.bilibili.com/' + cid + '.xml'
  2893. let sdanmu = await xhrGet(url)
  2894. ondanmu = ndanmu = Number(/<maxlimit>(.*?)</.exec(sdanmu)[1])
  2895. ldanmu = xml2danmu(sdanmu)
  2896. while (true) {
  2897. if (firstdate !== 0) {
  2898. await sleep(2000)
  2899. }
  2900. if (firstdate === 0 || ldanmu.length >= Math.min(ondanmu, 5000) * 0.5) {
  2901. let url = "https://api.bilibili.com/x/v2/dm/web/history/seg.so?type=1&date="
  2902. + dateObjectToDateStr(date) + "&oid=" + cid.toString();
  2903. console.log('ndanmu:', aldanmu.length, dateObjectToDateStr(date), url);
  2904. ldanmu = await loadProtoDanmu(url)
  2905. }
  2906. aldanmu = mergeDanmu(aldanmu, ldanmu)
  2907. document.title = aldanmu.length.toString()
  2908. toastText(dateObjectToDateStr(date) + '/' + aldanmu.length)
  2909. if (ldanmu.length < Math.min(ondanmu, 5000) * 0.5) {
  2910. return [aldanmu, ondanmu]
  2911. }
  2912. if (ldanmu.length >= Math.min(ondanmu, 5000) * 0.5) {
  2913. let tfirstdate = getMinDate(ldanmu)
  2914. if (firstdate !== 0 && firstdate - tfirstdate < 86400)
  2915. tfirstdate = firstdate - 86400;
  2916. firstdate = tfirstdate;
  2917. date.setTime(firstdate * 1000);
  2918. }
  2919. if (videoPublishDate && currentSetting.capturePeriodStart !== 0) {
  2920. if (videoPublishDate + currentSetting.capturePeriodStart > date.getTime() / 1000) {
  2921. return [aldanmu, ondanmu]
  2922. }
  2923. }
  2924. }
  2925. }
  2926.  
  2927.  
  2928. function timestampToFullDateStr(timestamp) {
  2929. const date = new Date(timestamp * 1000); // Convert seconds to milliseconds
  2930. const year = date.getFullYear();
  2931. const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Month is zero-indexed
  2932. const day = date.getDate().toString().padStart(2, '0');
  2933. const hour = date.getHours().toString().padStart(2, '0');
  2934. const minute = date.getMinutes().toString().padStart(2, '0');
  2935. const second = date.getSeconds().toString().padStart(2, '0');
  2936.  
  2937. return `${year}-${month}-${day}-${hour}-${minute}-${second}`;
  2938. }
  2939.  
  2940.  
  2941. function dateObjectToDateStr(date) {
  2942. const year = date.getFullYear();
  2943. const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Month is zero-indexed
  2944. const day = date.getDate().toString().padStart(2, '0');
  2945.  
  2946. return `${year}-${month}-${day}`;
  2947. }
  2948.  
  2949.  
  2950. function getMinDate(ldanmu) {
  2951. let minDate = ldanmu[0].ctime
  2952. for (let danmu of ldanmu) {
  2953. if (minDate > danmu.ctime) {
  2954. minDate = danmu.ctime
  2955. }
  2956. }
  2957. return minDate
  2958. }
  2959.  
  2960. function mergeDanmu(oldanmu, nldanmu) {
  2961. if (oldanmu.idPool === undefined) {
  2962.  
  2963. let idPool = new Set()
  2964. for (let danmu of oldanmu) {
  2965. try {
  2966. idPool.add(danmu.progress * danmu.content.length * parseInt(danmu.midHash, 16))
  2967.  
  2968. } catch (e) {
  2969. console.log(danmu)
  2970. console.log(e)
  2971. throw e
  2972. }
  2973. }
  2974. oldanmu.idPool = idPool
  2975. }
  2976. try {
  2977. for (let danmu of nldanmu) {
  2978. let ida = (danmu.progress ? danmu.progress : 1) * danmu.content.length * parseInt(danmu.midHash, 16)
  2979. if (!oldanmu.idPool.has(ida)) {
  2980. oldanmu.push(danmu)
  2981. oldanmu.idPool.add(ida)
  2982. }
  2983. }
  2984. } catch (e) {
  2985. console.log()
  2986. }
  2987.  
  2988. return oldanmu
  2989. }
  2990.  
  2991. function poolSize2Duration(poolSize) {
  2992. let lPoolSize = [
  2993. [0, 100],
  2994. [30, 300],
  2995. [60, 500],
  2996. [180, 1000],
  2997. [600, 1500],
  2998. [900, 3000],
  2999. [1500, 4000],
  3000. [2400, 6000],
  3001. [3600, 8000],
  3002. ]
  3003.  
  3004. for (let i = 0; i < lPoolSize.length; i += 1) {
  3005. if (poolSize === lPoolSize[i][1]) {
  3006. return lPoolSize[i][0]
  3007. }
  3008. }
  3009. }
  3010.  
  3011. async function allProtobufDanmu(cid, duration) {
  3012. toastText("实时弹幕:", cid)
  3013. let segIndex = 0, aldanmu = []
  3014. while (true) {
  3015. segIndex += 1
  3016. let tldanmu = await loadProtoDanmu('https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid='
  3017. + cid + '&segment_index=' + segIndex)
  3018. mergeDanmu(aldanmu, tldanmu)
  3019. toastText(aldanmu.length)
  3020. if ((!duration || segIndex * 360 > duration) && (!tldanmu || tldanmu.length === 0)) {
  3021. break
  3022. }
  3023. await sleep(500)
  3024. }
  3025. toastText('下载完成')
  3026. return aldanmu
  3027. }
  3028.  
  3029. async function allProtobufDanmuXml(cid, title, ndanmu) {
  3030. let ldanmu = savedanmuStandalone(danmuObject2XML(await allProtobufDanmu(cid, poolSize2Duration(ndanmu))))
  3031. downloadFile(validateTitle(title) + '.xml', ldanmu)
  3032. }
  3033.  
  3034. async function downloadDanmaku(cid, info) {
  3035. toastText("全弹幕:" + cid)
  3036. if (currentSetting.capturePeriodStart !== 0 || currentSetting.capturePeriodEnd !== -1) {
  3037. toastText("下载时段:第" + currentSetting.capturePeriodStart + '-' +
  3038. currentSetting.capturePeriodEnd + '天')
  3039. toastText(videoPublishDate ? "视频发布日期:" + dateObjectToDateStr(new Date(videoPublishDate * 1000)) : "未知日期:由弹幕判断")
  3040. }
  3041. let [ldanmu, ndanmu] = await moreHistory(cid)
  3042. if (ldanmu.length > ndanmu * 2
  3043. || (
  3044. (currentSetting.capturePeriodStart !== 0 || currentSetting.capturePeriodEnd !== -1) && ldanmu.length > ndanmu * 0.8
  3045. )
  3046. ) {
  3047. let sldanmu = await allProtobufDanmu(cid, poolSize2Duration(ndanmu))
  3048. mergeDanmu(ldanmu, sldanmu)
  3049. }
  3050. if (currentSetting.capturePeriodStart !== 0 || currentSetting.capturePeriodEnd !== -1) {
  3051. let publishDate = videoPublishDate || getMinDate(ldanmu)
  3052. let start = publishDate + currentSetting.capturePeriodStart * 86400 - 1
  3053. let end = currentSetting.capturePeriodEnd > 0 ?
  3054. publishDate + currentSetting.capturePeriodEnd * 86400 :
  3055. 1e12
  3056. console.log('before', ldanmu.length)
  3057. ldanmu = ldanmu.filter(danmu => {
  3058. return danmu.ctime > start && danmu.ctime < end
  3059. })
  3060. console.log('after', ldanmu.length)
  3061. }
  3062. if (!info) {
  3063. info = {}
  3064. }
  3065. info.cid = cid
  3066. info.ndanmu = ndanmu
  3067.  
  3068. toastText('下载完成')
  3069. return new DownloadResult(ldanmu, info)
  3070. }
  3071.  
  3072. class DownloadResult {
  3073. constructor(ldanmu, info) {
  3074. this.ldanmu = ldanmu
  3075. this.info = info
  3076. }
  3077.  
  3078. toXml() {
  3079. return savedanmuStandalone(danmuObject2XML(this.ldanmu), this.info)
  3080. }
  3081.  
  3082. dumpFile(title) {
  3083. downloadFile(validateTitle(title) + '.xml', this.toXml())
  3084. }
  3085.  
  3086. splitByTime(folder) {
  3087. this.ldanmu.sort((a, b) => {
  3088. return a.ctime - b.ctime
  3089. })
  3090.  
  3091. let i = 0
  3092. const chunkSize = 3000
  3093. while (i * chunkSize < this.ldanmu.length) {
  3094. let tldanmu = this.ldanmu.slice(i * chunkSize, (i + 1) * chunkSize)
  3095. let lastTs = tldanmu[tldanmu.length - 1].ctime
  3096. let fileName = timestampToFullDateStr(lastTs) + '_' + this.info.cid + '.xml'
  3097. folder.file(fileName, new DownloadResult(tldanmu, this.info).toXml())
  3098. i += 1
  3099. }
  3100. }
  3101. }
  3102.  
  3103. async function downloadDanmakuToZip(cid, folder, partTitle, partInfo, spiltFileFlag) {
  3104. let result = await downloadDanmaku(cid, '', partInfo)
  3105. if (!spiltFileFlag) {
  3106. let sdanmu = result.toXml()
  3107. await sleep(1);
  3108. folder.file(partTitle + '.xml', sdanmu)
  3109. await sleep(1);
  3110. } else {
  3111. let partFolder = folder.folder(partTitle)
  3112. result.splitByTime(partFolder)
  3113. }
  3114. }
  3115.  
  3116. return [
  3117. downloadDanmaku,
  3118.  
  3119. downloadDanmakuToZip,
  3120.  
  3121. allProtobufDanmuXml
  3122. ]
  3123. })();
  3124.  
  3125. let downloadDanmakuVideo = (() => {
  3126.  
  3127. return async function (videoInfo) {
  3128. let zip = new JSZip();
  3129. let title
  3130. let aid
  3131. if (typeof videoInfo['aid'] === 'number') {
  3132. aid = videoInfo['aid']
  3133. title = 'av' + videoInfo['aid'] + ' ' + validateTitle(videoInfo['title'])
  3134. } else {
  3135. title = videoInfo['aid'] + ' ' + validateTitle(videoInfo['title'])
  3136. aid = Number(videoInfo['aid'].substring(2))
  3137. }
  3138. title = validateTitle(title)
  3139. console.log('title= ' + title)
  3140. let folder = zip.folder(title)
  3141. folder.file('videoInfo.json', JSON.stringify(videoInfo))
  3142. let i = 0
  3143.  
  3144. if (typeof videoInfo['aid'] === 'number' || videoInfo['aid'].startsWith('av')) {
  3145. try {
  3146. let pageList = JSON.parse(await xhrGet(`https://api.bilibili.com/x/player/pagelist?aid=${aid}&jsonp=jsonp`))
  3147. if (pageList.code === 0) {
  3148. for (let page of pageList['data']) {
  3149. let matched = false
  3150. for (let part of videoInfo['list']) {
  3151. if (part.cid === page.cid) {
  3152. part.duration = page.duration
  3153. matched = true
  3154. break
  3155. }
  3156. }
  3157. if (!matched) {
  3158. videoInfo['list'].push(page)
  3159. }
  3160. }
  3161. }
  3162. } catch (e) {
  3163. console.error(e, e.stack)
  3164. }
  3165. }
  3166.  
  3167.  
  3168. if (videoInfo.videoPublishDate) {
  3169. videoPublishDate = videoInfo.videoPublishDate
  3170. }
  3171.  
  3172. for (let partInfo of videoInfo['list']) {
  3173. i += 1
  3174. partInfo.title = partInfo.part
  3175. partInfo.aid = aid
  3176. let partTitle = /^\d$/.test(partInfo.page) ? 'p' : ''
  3177. partTitle += partInfo.page + ' ' + validateTitle(partInfo.part) + '_' + partInfo.cid
  3178. if (partInfo.videoPublishDate) {
  3179. videoPublishDate = partInfo.videoPublishDate
  3180. }
  3181. toastText(partTitle)
  3182. let progress = (i * 100 / videoInfo['list'].length).toFixed(2)
  3183. document.title = progress + ' %'
  3184. await downloadDanmakuToZip(partInfo.cid, folder, partTitle, partInfo, currentSetting['splitFileByTime'])
  3185. broadcastChannel.postMessage({
  3186. type: 'cidComplete',
  3187. cid: partInfo.cid,
  3188. aid: videoInfo.aid,
  3189. progress: progress,
  3190. }, '*');
  3191. if (partInfo.videoPublishDate) {
  3192. videoPublishDate = null
  3193. }
  3194. }
  3195. let result = await zip.generateAsync({
  3196. type: "blob", compression: "DEFLATE",
  3197. compressionOptions: {
  3198. level: 9
  3199. }
  3200. })
  3201. videoPublishDate = null
  3202. downloadFile(title + '.zip', result);
  3203. }
  3204. })()
  3205.  
  3206. let downloadedCid = []
  3207. let downloadedAid = []
  3208. let downloadingVideo = []
  3209. broadcastChannel.addEventListener('message', async (e) => {
  3210. if (e.data.type === 'biliplusDownloadDanmaku') {
  3211. if (e.data.history !== false) {
  3212. if (downloadedCid.indexOf(e.data.cid) !== -1) {
  3213. return
  3214. }
  3215. downloadedCid.push(e.data.cid);
  3216. (await downloadDanmaku(e.data.cid, e.data)).dumpFile(e.data.title)
  3217. } else {
  3218. await allProtobufDanmu(e.data.cid, e.data.title, e.data.ndanmu)
  3219. }
  3220. }
  3221. if (e.data.type === 'biliplusDownloadDanmakuVideo') {
  3222. if (downloadedAid.indexOf(e.data.videoInfo.aid) !== -1) {
  3223. broadcastChannel.postMessage({type: 'aidDownloaded', aid: e.data.videoInfo.aid}, '*');
  3224. return
  3225. }
  3226. downloadedAid.push(e.data.videoInfo.aid)
  3227. if (downloadingVideo.length === 0) {
  3228. downloadingVideo.push(e.data.videoInfo)
  3229. while (downloadingVideo.length !== 0) {
  3230. let videoInfo = downloadingVideo[0]
  3231. console.log('start', videoInfo.aid)
  3232. broadcastChannel.postMessage({type: 'aidStart', aid: videoInfo.aid}, '*');
  3233. await new Promise((resolve) => setTimeout(resolve, 1));
  3234. await downloadDanmakuVideo(videoInfo)
  3235. document.title = '下载完成'
  3236. broadcastChannel.postMessage({type: 'aidComplete', aid: videoInfo.aid}, '*');
  3237. await sleep(1000)
  3238. downloadingVideo = downloadingVideo.slice(1)
  3239. }
  3240. } else {
  3241. console.log('wait', e.data.videoInfo.aid)
  3242. downloadingVideo.push(e.data.videoInfo)
  3243. }
  3244.  
  3245. }
  3246. });
  3247. }
  3248.  
  3249. let currentSetting = panel()
  3250. client()
  3251. server()
  3252.  
  3253.  
  3254. })();