@dan-uni/dan-any-plugin-detaolu 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,25 +1,44 @@
1
- # dan-any-plugin-detaolu 弹幕随心转(反套路插件)
1
+ # @dan-uni/dan-any-plugin-detaolu
2
2
 
3
- [![Publish @dan-uni/dan-any-plugin-detaolu](https://github.com/ani-uni/danuni/actions/workflows/npm-dan-any-plugin-detaolu.yml/badge.svg)](https://github.com/ani-uni/danuni/actions/workflows/npm-dan-any-plugin-detaolu.yml)
3
+ `@dan-uni/dan-any-plugin-detaolu` 基于 `pakku.js` 的思路实现了一套弹幕去重 / 反套路(反“taolu”)合并插件,用于在 `dan-any` 数据流中把相似或重复的弹幕聚合为代表弹幕。
4
4
 
5
- ## Features
5
+ 主要功能
6
6
 
7
- 基于 pakku.js[^1] 核心功能制作的弹幕过滤器,使用参数及全部功能可参见其仓库。
7
+ - 使用相似度算法(编辑距离、2-gram 词频向量、拼音归一化等)识别并合并相近弹幕
8
+ - 提供 `DetaoluPluginConfigurator` 作为 `dan-any` plugin,直接用于 `chunk.plugin(...)`
9
+ - 暴露可配置项(参见 `src/pakku.js/index.ts` 中的 `DEFAULT_CONFIG`)以调节合并策略
8
10
 
9
- ## Usage 使用方法
11
+ 快速开始
12
+
13
+ ```bash
14
+ vp install
15
+ vp test
16
+ vp pack
17
+ ```
18
+
19
+ 使用示例
10
20
 
11
21
  ```ts
12
- import { UniPool } from "@dan-uni/dan-any";
13
- import detaolu from "@dan-uni/dan-any-plugin-detaolu";
22
+ import { DetaoluPluginConfigurator } from "@dan-uni/dan-any-plugin-detaolu";
14
23
 
15
- const pool = UniPool.create();
16
- const d = (await pool.pipe(detaolu({ MAX_COSINE: 1000 }))).minify();
17
- console.log(d);
24
+ // dan-any 的处理链中使用:
25
+ const mergedChunk = await chunk.plugin(DetaoluPluginConfigurator({ THRESHOLD: 30 }));
26
+ // mergedChunk 包含合并/聚合后的弹幕
18
27
  ```
19
28
 
20
- ## License 许可证
29
+ 配置
30
+
31
+ - 默认配置项位于 `src/pakku.js/index.ts` 中的 `DEFAULT_CONFIG`,包含合并阈值、编辑距离阈值、词频相似度阈值、白名单/黑名单与若干文本预处理选项。
32
+
33
+ 许可与致谢
34
+
35
+ - 本包采用 GPL-3.0-or-later 许可(详见 `package.json`)。
36
+ - 相似度与合并逻辑源自并改编自开源项目 `pakku.js`(参见源码注释),请注意原作者许可约束。
37
+
38
+ 贡献
39
+
40
+ - 欢迎提交 issue 与 PR。提交前请运行 `vp check` 与 `vp test` 并确保遵守 GPL 兼容要求。
21
41
 
22
- Released under the GNU GENERAL PUBLIC LICENSE (GPL) 3.0.
23
- 本库采用 GPL 3.0 or later 许可证发布。
42
+ 更多
24
43
 
25
- [^1]: 对于`src/pakku.js`内的文件,使用了[xmcp/pakku.js](https://github.com/xmcp/pakku.js)的代码(GPL-3.0 LICENSE),并对其进行了一定修改使其可在该项目下使用。
44
+ - 源码主要位于 `src/pakku.js`(实现合并算法与 wasm 加载)和 `src/index.ts`(提供 `DetaoluPluginConfigurator` 集成点)。
@@ -0,0 +1,66 @@
1
+ import { UniChunk } from "@dan-uni/dan-any/core";
2
+ //#region src/pakku.js/index.d.ts
3
+ declare const DEFAULT_CONFIG: {
4
+ /**
5
+ * 时间阈值:合并时间差在n秒之内的重复弹幕
6
+ * 超长(大概 60 秒以上?)的阈值可能会导致程序运行缓慢
7
+ */
8
+ THRESHOLD: number;
9
+ /**
10
+ * 编辑距离合并阈值:
11
+ * 根据编辑距离判断不完全一致但内容相近(例如有错别字)的弹幕
12
+ * 能有效击杀 "你指尖跃动的电光" 和 "你之间跃动的电光" 等
13
+ * @example 禁用(0), 轻微(≤3), 中等(≤5), 强力(≤8)
14
+ */
15
+ MAX_DIST: number;
16
+ /**
17
+ * 词频向量合并阈值:
18
+ * 根据 2-Gram 频率向量的夹角判断不完全一致但内容类似的弹幕
19
+ * 能有效击杀 "yeah!~" 和 "yeah!~yeah!~yeah!~yeah!~" 等
20
+ * @example 禁用(1000), 轻微(60%), 中等(45%), 强力(30%)
21
+ */
22
+ MAX_COSINE: number;
23
+ /**
24
+ * 识别谐音弹幕:
25
+ * 将常用汉字转换为拼音再进行比较
26
+ * 能有效击杀 "布拉迪巴特福来" 和 "布拉迪·八德福莱" 等
27
+ */
28
+ TRIM_PINYIN: boolean;
29
+ TRIM_ENDING: boolean;
30
+ TRIM_SPACE: boolean;
31
+ TRIM_WIDTH: boolean;
32
+ /**
33
+ * 内容替换:符合这些规则的弹幕,判断是否合并前会先对内容进行替换
34
+ */
35
+ FORCELIST: string[][];
36
+ /**
37
+ * 内容替换规则命中时:继续尝试匹配后续规则
38
+ */
39
+ FORCELIST_CONTINUE_ON_MATCH: boolean;
40
+ /**
41
+ * 内容替换规则命中时:即使未触发合并也使用替换后的文本
42
+ */
43
+ FORCELIST_APPLY_SINGULAR: boolean;
44
+ /**
45
+ * 强制忽略:符合这些规则的弹幕不会被合并,优先级高于内容替换规则
46
+ */
47
+ WHITELIST: [string, string][];
48
+ /**
49
+ * 强制删除:符合这些规则的弹幕会直接被删除(未实现)
50
+ */
51
+ BLACKLIST: [string, string][];
52
+ /**
53
+ * 合并不同类型的弹幕(取消勾选后,底部弹幕不会跟滚动弹幕合并到一起)
54
+ */
55
+ CROSS_MODE: boolean;
56
+ PROC_TYPE7: boolean;
57
+ PROC_TYPE4: boolean;
58
+ PROC_POOL1: boolean;
59
+ };
60
+ type Config = Partial<typeof DEFAULT_CONFIG>;
61
+ //#endregion
62
+ //#region src/index.d.ts
63
+ declare const DetaoluPluginConfigurator: (config?: Config) => (uchunk: UniChunk) => Promise<UniChunk>;
64
+ //#endregion
65
+ export { DetaoluPluginConfigurator };
66
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/pakku.js/index.ts","../src/index.ts"],"mappings":";;cAuBa,cAAA;EA0BX;;;;EApBA,SAAA;EAqCA;;;;;;EA9BA,QAAA;EAkDA;;;AA0BF;;;EArEE,UAAA;EAqEgD;;;;ACxGlD;EDyCE,WAAA;EAEA,WAAA;EACA,UAAA;EACA,UAAA;EC7C8D;;;EDmD9D,SAAA;ECnDiD;;;ED0DjD,2BAAA;EC1D8D;;;ED8D9D,wBAAA;;;;EAIA,SAAA;;;;EAIA,SAAA;;;;EAIA,UAAA;EAEA,UAAA;EACA,UAAA;EACA,UAAA;AAAA;AAAA,KA0BU,MAAA,GAAS,OAAA,QAAe,cAAA;;;cCxGvB,yBAAA,GAAyB,MAAA,GAAa,MAAA,MAAa,MAAA,EAAA,QAAA,KAAA,OAAA,CAAA,QAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{UniChunk as e}from"@dan-uni/dan-any/core";import{readFile as t}from"node:fs/promises";import{join as n}from"node:path";import{BiliCommonModeRec as r,definePlugin as i,enumPoolCodec as a}from"@dan-uni/dan-any/adapters";import{GetStatsTransformerConfigurator as o,GetStatsUtil4getMost as s}from"@dan-uni/dan-any/plugins";var c=function(e={}){var t,n=e,r,i=new Promise(e=>{r=e});`_begin_chunk _check_similar _begin_index_lock _malloc _memory ___indirect_function_table onRuntimeInitialized`.split(` `).forEach(e=>{Object.getOwnPropertyDescriptor(i,e)||Object.defineProperty(i,e,{get:()=>c(`You are getting `+e+` on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js`),set:()=>c(`You are setting `+e+` on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js`)})});var a=e=>console.log(e),o=e=>console.error(e);a=()=>{},o=e=>{throw console.error(e),Error(`wasm error: `+e)};function s(e,t){if(!e)throw t}function c(e){throw Error(e)}var l,u,d,f;function p(){var e=f.buffer;new Int8Array(e),l=new Int16Array(e),u=new Uint8Array(e),new Uint16Array(e),new Int32Array(e),d=new Uint32Array(e),new Float32Array(e),new Float64Array(e),new BigInt64Array(e),new BigUint64Array(e)}s(Math.imul,`This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill`),s(Math.fround,`This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill`),s(Math.clz32,`This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill`),s(Math.trunc,`This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill`);var m=new Int16Array(1),h=new Int8Array(m.buffer);if(m[0]=25459,h[0]!==115||h[1]!==99)throw`Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)`;if(n.ENVIRONMENT)throw Error(`Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)`);function g(e){return e===`FS_createPath`||e===`FS_createDataFile`||e===`FS_createPreloadedFile`||e===`FS_unlink`||e===`addRunDependency`||e===`FS_createLazyFile`||e===`FS_createDevice`||e===`removeRunDependency`}function _(e,t){typeof globalThis>`u`||Object.getOwnPropertyDescriptor(globalThis,e)||Object.defineProperty(globalThis,e,{configurable:!0,get(){t()}})}function v(e,t){_(e,()=>{b(`\`${e}\` is not longer defined by emscripten. ${t}`)})}v(`buffer`,`Please use HEAP8.buffer or wasmMemory.buffer`),v(`asm`,`Please use wasmExports instead`);function y(e){Object.getOwnPropertyDescriptor(n,e)||Object.defineProperty(n,e,{configurable:!0,get(){var t=`'${e}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;g(e)&&(t+=`. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you`),c(t)}})}var b=e=>{b.g||={},b.g[e]||(b.g[e]=1,o(e))},x=typeof TextDecoder<`u`?new TextDecoder:void 0,S=[null,[],[]],C={_abort_js:()=>c(`native code called abort()`),emscripten_resize_heap:e=>{var t=u.length;if(e>>>=0,s(e>t),268435456<e)return o(`Cannot enlarge memory, requested ${e} bytes, but the limit is 268435456 bytes!`),!1;for(var n=1;4>=n;n*=2){var r=t*(1+1/n);r=Math.min(r,e+100663296);var i=Math,a=i.min;r=Math.max(e,r),s(65536,`alignment argument is required`),i=a.call(i,268435456,65536*Math.ceil(r/65536));a:{a=i,r=f.buffer;var c=(a-r.byteLength+65535)/65536|0;try{f.grow(c),p();var l=1;break a}catch(e){o(`growMemory: Attempted to grow heap from ${r.byteLength} bytes to ${a} bytes, but got error: ${e}`)}l=void 0}if(l)return!0}return o(`Failed to grow the heap from ${t} bytes to ${i} bytes, not enough memory!`),!1},fd_close:()=>{c(`fd_close called without SYSCALLS_REQUIRE_FILESYSTEM`)},fd_seek:function(){return 70},fd_write:(e,t,n,r)=>{for(var i=0,c=0;c<n;c++){var l=d[t>>2],f=d[t+4>>2];t+=8;for(var p=0;p<f;p++){var m=e,h=u[l+p],g=S[m];if(s(g),h===0||h===10){m=m===1?a:o,h=g;for(var _=0,v=_+NaN,y=_;h[y]&&!(y>=v);)++y;if(16<y-_&&h.buffer&&x)h=x.decode(h.subarray(_,y));else{for(v=``;_<y;){var C=h[_++];if(C&128){var w=h[_++]&63;if((C&224)==192)v+=String.fromCharCode((C&31)<<6|w);else{var T=h[_++]&63;if((C&240)==224)C=(C&15)<<12|w<<6|T;else{if((C&248)!=240){var E=b,D=C;s(typeof D==`number`),D=`0x`+(D>>>0).toString(16).padStart(8,`0`),E(`Invalid UTF-8 leading byte `+D+` encountered when deserializing a UTF-8 string in wasm memory to a JS string!`)}C=(C&7)<<18|w<<12|T<<6|h[_++]&63}65536>C?v+=String.fromCharCode(C):(C-=65536,v+=String.fromCharCode(55296|C>>10,56320|C&1023))}}else v+=String.fromCharCode(C)}h=v}m(h),g.length=0}else g.push(h)}i+=f}return d[r>>2]=i,0}};n.stringToUTF16=(e,t,n)=>{if(s(t%2==0,`Pointer passed to stringToUTF16 must be aligned to two bytes!`),s(typeof n==`number`,`stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!`),n??=2147483647,2>n)return 0;n-=2;var r=t;n=n<2*e.length?n/2:e.length;for(var i=0;i<n;++i)l[t>>1]=e.charCodeAt(i),t+=2;return l[t>>1]=0,t-r},`writeI53ToI64 writeI53ToI64Clamped writeI53ToI64Signaling writeI53ToU64Clamped writeI53ToU64Signaling readI53FromI64 readI53FromU64 convertI32PairToI53 convertI32PairToI53Checked convertU32PairToI53 stackSave stackRestore stackAlloc getTempRet0 setTempRet0 zeroMemory strError inetPton4 inetNtop4 inetPton6 inetNtop6 readSockaddr writeSockaddr emscriptenLog readEmAsmArgs jstoi_q getExecutableName listenOnce autoResumeAudioContext getDynCaller dynCall callUserCallback asmjsMangle asyncLoad mmapAlloc HandleAllocator getNativeTypeSize STACK_SIZE STACK_ALIGN POINTER_SIZE ASSERTIONS getCFunc ccall cwrap uleb128Encode sigToWasmTypes generateFuncType convertJsFunctionToWasm getEmptyTableSlot updateTableMap getFunctionAddress addFunction removeFunction reallyNegative unSign strLen reSign formatString setValue getValue stringToUTF8Array stringToUTF8 lengthBytesUTF8 intArrayFromString intArrayToString AsciiToString stringToAscii UTF16ToString lengthBytesUTF16 UTF32ToString stringToUTF32 lengthBytesUTF32 stringToNewUTF8 stringToUTF8OnStack writeArrayToMemory registerKeyEventCallback maybeCStringToJsString findEventTarget getBoundingClientRect fillMouseEventData registerMouseEventCallback registerWheelEventCallback registerUiEventCallback registerFocusEventCallback fillDeviceOrientationEventData registerDeviceOrientationEventCallback fillDeviceMotionEventData registerDeviceMotionEventCallback screenOrientation fillOrientationChangeEventData registerOrientationChangeEventCallback fillFullscreenChangeEventData registerFullscreenChangeEventCallback JSEvents_requestFullscreen JSEvents_resizeCanvasForFullscreen registerRestoreOldStyle hideEverythingExceptGivenElement restoreHiddenElements setLetterbox softFullscreenResizeWebGLRenderTarget doRequestFullscreen fillPointerlockChangeEventData registerPointerlockChangeEventCallback registerPointerlockErrorEventCallback requestPointerLock fillVisibilityChangeEventData registerVisibilityChangeEventCallback registerTouchEventCallback fillGamepadEventData registerGamepadEventCallback registerBeforeUnloadEventCallback fillBatteryEventData battery registerBatteryEventCallback setCanvasElementSize getCanvasElementSize jsStackTrace getCallstack convertPCtoSourceLocation getEnvStrings checkWasiClock wasiRightsToMuslOFlags wasiOFlagsToMuslOFlags initRandomFill randomFill safeSetTimeout setImmediateWrapped safeRequestAnimationFrame clearImmediateWrapped polyfillSetImmediate registerPostMainLoop registerPreMainLoop getPromise makePromise idsToPromises makePromiseCallback isLeapYear ydayFromDate arraySum addDays getSocketFromFD getSocketAddress ALLOC_NORMAL ALLOC_STACK allocate writeStringToMemory writeAsciiToMemory setErrNo demangle stackTrace`.split(` `).forEach(function(e){_(e,()=>{var t=`\`${e}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`,n=e;n.startsWith(`_`)||(n=`$`+e),t+=` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${n}')`,g(e)&&(t+=`. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you`),b(t)}),y(e)}),`run addOnPreRun addOnInit addOnPreMain addOnExit addOnPostRun addRunDependency removeRunDependency out err callMain abort wasmMemory wasmExports HEAPF32 HEAPF64 HEAP_DATA_VIEW HEAP8 HEAPU8 HEAP16 HEAPU16 HEAP32 HEAPU32 HEAP64 HEAPU64 writeStackCookie checkStackCookie INT53_MAX INT53_MIN bigintToI53Checked ptrToString getHeapMax growMemory ENV ERRNO_CODES DNS Protocols Sockets timers warnOnce readEmAsmArgsArray jstoi_s alignMemory wasmTable noExitRuntime freeTableIndexes functionsInTableMap PATH PATH_FS UTF8Decoder UTF8ArrayToString UTF8ToString UTF16Decoder JSEvents specialHTMLTargets findCanvasEventTarget currentFullscreenStrategy restoreOldWindowedStyle UNWIND_CACHE promiseMap MONTH_DAYS_REGULAR MONTH_DAYS_LEAP MONTH_DAYS_REGULAR_CUMULATIVE MONTH_DAYS_LEAP_CUMULATIVE SYSCALLS allocateUTF8 allocateUTF8OnStack print printErr`.split(` `).forEach(y);var w,T,E={env:C,wasi_snapshot_preview1:C};if(!n.wasm)throw`Must load WebAssembly Module in to variable Module.wasm before adding compiled output .js script to the DOM`;WebAssembly.instantiate(n.wasm,E).then(e=>{e=e.instance.exports,n._begin_chunk=e.begin_chunk,n._begin_index_lock=e.begin_index_lock,n._check_similar=e.check_similar,n._malloc=e.malloc,w=e.emscripten_stack_init,T=e.emscripten_stack_get_end,f=e.memory,s(f),p(),w();var t=T();s((t&3)==0),t==0&&(t+=4),d[t>>2]=34821223,d[t+4>>2]=2310721022,e.__wasm_call_ctors(),r(n),a(`ready() called, and INVOKE_RUN=0. The runtime is now ready for you to call run() to invoke application _main(). You can also override ready() in a --pre-js file to get this signal as a callback`)},e=>{console.error(e)}),t=i;for(let t of Object.keys(n))t in e||Object.defineProperty(e,t,{configurable:!0,get(){c(`Access to module property ('${t}') is no longer possible via the module constructor argument; Instead, use the result of the module constructor.`)}});return t};let l=null,u;const d=16005;async function f(e){l=await c({wasm:e}),u=l._malloc(d*2+7),u%2&&u++}function p(e){try{l._begin_chunk(u,e.MAX_DIST,e.MAX_COSINE,e.TRIM_PINYIN,e.CROSS_MODE)}catch(e){throw Error(`wasm error (begin_chunk):\n${e}`,{cause:e})}}function m(){try{l._begin_index_lock()}catch(e){throw Error(`wasm error (begin_index_lock):\n${e}`,{cause:e})}}function h(e,t,n,r){try{l.stringToUTF16(e,u,d*2)}catch(t){throw Error(`wasm error (write str buf): ${e}\n${t}`,{cause:t})}let i;try{i=l._check_similar(t,n)}catch(t){throw Error(`wasm error (similar): ${e}\n${t}`,{cause:t})}if(i===0)return null;i>>>=0;let a=i>>>30,o=i>>>19&2047,s=i&(1<<19)-1,c;switch(a){case 0:r.combined_identical++,c=`==`;break;case 1:r.combined_edit_distance++,c=`≤${o}`;break;case 3:r.combined_cosine_distance++,c=`${o}%`;break;case 2:r.combined_pinyin_distance++,c=`P≤${o}`;break;default:throw Error(`similarity wasm returned unknown reason: ${i}`)}return{reason:c,idx_diff:s}}var g=class{combined_identical=0;combined_edit_distance=0;combined_pinyin_distance=0;combined_cosine_distance=0;deleted_blacklist=0;deleted_blacklist_each={};ignored_whitelist=0;ignored_type=0;num_taolu_matched=0},_=class{storage;index_l;index_r;constructor(e=[]){this.storage={...e},this.index_l=0,this.index_r=e.length}push(e){this.storage[this.index_r++]=e}pop(){delete this.storage[this.index_l++]}peek(){return this.index_l===this.index_r?null:this.storage[this.index_l]}size(){return this.index_r-this.index_l}[Symbol.iterator](){let e=this,t=e.index_l;return{next(){return t>=e.index_r?{done:!0,value:void 0}:{done:!1,value:e.storage[t++]}}}}},v=`73f7e7f2dd1a4caa.wasm`;const y={THRESHOLD:30,MAX_DIST:5,MAX_COSINE:45,TRIM_PINYIN:!0,TRIM_ENDING:!0,TRIM_SPACE:!0,TRIM_WIDTH:!0,FORCELIST:[[`^23{2,}$`,`23333`],[`^6{3,}$`,`66666`]],FORCELIST_CONTINUE_ON_MATCH:!0,FORCELIST_APPLY_SINGULAR:!1,WHITELIST:[],BLACKLIST:[],CROSS_MODE:!0,PROC_TYPE7:!0,PROC_TYPE4:!0,PROC_POOL1:!1},b=new Set(`.。,,/??!!…~~@^、+=-_♂♀ `),x=new Map(Object.entries({" ":` `,"1":`1`,"2":`2`,"3":`3`,"4":`4`,"5":`5`,"6":`6`,"7":`7`,"8":`8`,"9":`9`,"0":`0`,"!":`!`,"@":`@`,"#":`#`,"$":`$`,"%":`%`,"^":`^`,"&":`&`,"*":`*`,"(":`(`,")":`)`,"-":`-`,"=":`=`,"_":`_`,"+":`+`,"[":`[`,"]":`]`,"{":`{`,"}":`}`,";":`;`,"'":`'`,":":`:`,""":`"`,",":`,`,".":`.`,"/":`/`,"<":`<`,">":`>`,"?":`?`,"\":`\\`,"|":`|`,"`":"`","~":`~`,q:`q`,w:`w`,e:`e`,r:`r`,t:`t`,y:`y`,u:`u`,i:`i`,o:`o`,p:`p`,a:`a`,s:`s`,d:`d`,f:`f`,g:`g`,h:`h`,j:`j`,k:`k`,l:`l`,z:`z`,x:`x`,c:`c`,v:`v`,b:`b`,n:`n`,m:`m`,Q:`Q`,W:`W`,E:`E`,R:`R`,T:`T`,Y:`Y`,U:`U`,I:`I`,O:`O`,P:`P`,A:`A`,S:`S`,D:`D`,F:`F`,G:`G`,H:`H`,J:`J`,K:`K`,L:`L`,Z:`Z`,X:`X`,C:`C`,V:`V`,B:`B`,N:`N`,M:`M`}));function S(e){let t=e.TRIM_ENDING,n=e.TRIM_SPACE,r=e.TRIM_WIDTH,i=e.FORCELIST.map(([e,t])=>[new RegExp(e,`giu`),t]),a=!e.FORCELIST_CONTINUE_ON_MATCH;return e=>{let o=e.length,s=``;if(t){for(;b.has(e.charAt(o-1));)o--;o===0&&(o=e.length)}if(r)for(let t=0;t<o;t++){let n=e.charAt(t);s+=x.get(n)||n}else s=e.slice(0,o);n&&(s=s.replaceAll(/[ \u3000]+/g,` `).replaceAll(/([\u3000-\u9FFF\uFF00-\uFFEF]) (?=[\u3000-\u9FFF\uFF00-\uFFEF])/g,`$1`));let c=!1;for(let e of i)if(e[0].test(s)&&(s=s.replace(e[0],e[1]),c=!0,a))break;return[c,s]}}function C(e){let t=e.WHITELIST.map(e=>new RegExp(e[0],`iu`));return t.length===0?()=>!1:e=>t.some(t=>t.test(e))}function w(e){let t=e.BLACKLIST.map(e=>e[0]?new RegExp(e[1]):e[1].toLowerCase());return t.length===0?()=>null:e=>{let n=e.toLowerCase();for(let r of t)if(typeof r==`string`?n.includes(r):r.test(e))return typeof r==`string`?` ${r}`:` /${r.source}/`;return null}}function T(e){try{e=JSON.parse(e)[4]}catch{}return e}function E(e){return e.replaceAll(/([\r\n\t])/g,``).trim()}function D(e){if(e.length===1)return e[0];let t=e.toSorted((e,t)=>e.length-t.length);return t[Math.floor(t.length/2)]}function O(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}async function k(e){if(e){await f(e);return}await f(O(await t(new URL(n(import.meta.url,`../../..`,v)).pathname)))}function A(e,t){return t?-1-e:e}async function j(e,t=y){let n={...y,...t};await k(),p(n);let r={clusters:[],stats:new g,deleted_chunk:[]};function i(e,t,n){r.clusters.push({peers_ptr:[[e,`IGN`]],desc:[n],chosen_str:t.content,danuni_count:1,danuni_dans:[t]})}function a(e){if(e.length===1)r.clusters.push({peers_ptr:e.map(e=>[e.ptr_idx,e.sim_reason]),desc:[],chosen_str:e[0].obj.content,danuni_count:e.length,danuni_dans:e.map(e=>e.obj)});else{let t=new Map,n=[],i=0;for(let r of e){let e=r.str,a=1+(t.get(e)||0);t.set(e,a),a>i?(n=[e],i=a):a===i&&n.push(e)}let a=D(n);r.clusters.push({peers_ptr:e.map(e=>[e.ptr_idx,e.sim_reason]),desc:i>1?[`采用了出现 ${i} 次的文本`]:[],chosen_str:a,danuni_count:i,danuni_dans:e.map(e=>e.obj)})}}let o=S(n),s=C(n),c=w(n);function l(e,t,a){return e.map((e,l)=>{if(!n.PROC_POOL1&&e.pool===1)return t&&(t.ignored_type++,i(l,e,`已忽略字幕弹幕,可以在选项中修改`)),null;if(!n.PROC_TYPE7&&e.mode===4)return t&&(t.ignored_type++,i(l,e,`已忽略特殊弹幕,可以在选项中修改`)),null;if(!n.PROC_TYPE4&&e.mode===1)return t&&(t.ignored_type++,i(l,e,`已忽略底部弹幕,可以在选项中修改`)),null;let u=E(e.mode===4&&e.content[0]===`[`?T(e.content):e.content);if(e.mode!==4){let n=c(u);if(n)return t&&(t.deleted_blacklist++,t.deleted_blacklist_each[n]=(t.deleted_blacklist_each[n]||0)+1,r.deleted_chunk.push({...e,pakku:{deleted_reason:`命中黑名单:${n}`}})),null}if(s(u))return t&&(t.ignored_whitelist++,i(l,e,`命中白名单`)),null;let[d,f]=o(u);return d&&(t&&t.num_taolu_matched++,n.FORCELIST_APPLY_SINGULAR&&(e={...e,content:f})),{obj:e,str:f,ptr_idx:A(l,a),sim_reason:`ORIG`}}).filter(e=>e!==null)}let u=l(e.objs,r.stats,!1),d=new _,f=n.THRESHOLD*1e3;for(let e of u){for(;;){let t=d.peek();if(t===null||e.obj.time_ms-t[0].obj.time_ms<=f)break;a(t),d.pop()}let t=h(e.str,e.obj.mode,d.index_l,r.stats);if(t===null)d.push([e]);else{let n=d.storage[d.index_r-t.idx_diff];e.sim_reason=t.reason,n.push(e)}}m();for(let e of d)a(e);return r}const M=t=>i(async n=>{let i=await e.makeChunk(n,{tmp:!0}),c=await j({objs:(await n.$danmakus).map(e=>({time_ms:e.progress,mode:r(e.mode),content:e.content,pool:a.encode(e.pool),danuni_dan:e}))},t),l=new Date,u=c.clusters.map(async e=>{if(e.danuni_dans.length===1)return e.danuni_dans[0].danuni_dan;{let t=e.danuni_dans.map(e=>e.danuni_dan),r=await o([`color`,`pool`,`platform`])(Promise.resolve(t)),i=t.map(e=>e.progress),a={ctime:l,SOID:t[0].SOID,progress:t[0].progress,mode:new Set(t.map(e=>e.mode)).size===1?t[0].mode:`Top`,fontsize:t.length>10?25:36,color:s(r.color).val??t[0].color,senderID:`detaolu[bot]@dan-any`,content:e.chosen_str,weight:10,pool:s(r.pool).val??t[0].pool,attr:[`Protect`],platform:s(r.platform).val??t[0].platform,extra:{danuni:{merge:{count:e.danuni_count,duration:Number.parseFloat((Math.max(...i)-Math.min(...i)).toFixed(3)),senders:t.filter(t=>t.content===e.chosen_str).map(e=>e.senderID),taolu_count:t.length,taolu_senders:t.map(e=>e.senderID)}}}};return{...a,DMID:n.$UniDB.DMIDGenerator(a)}}});return await i.upsertDanmakus(await Promise.all(u),!1),i});export{M as DetaoluPluginConfigurator};
2
+ //# sourceMappingURL=index.mjs.map