@applemusic-like-lyrics/core 0.3.1 → 0.4.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 +3 -3
- package/dist/amll-core.cjs +5020 -0
- package/dist/amll-core.cjs.map +1 -0
- package/dist/amll-core.d.cts +997 -0
- package/dist/amll-core.d.mts +997 -0
- package/dist/{amll-core.js → amll-core.mjs} +87 -5786
- package/dist/amll-core.mjs.map +1 -0
- package/dist/style.css +399 -0
- package/package.json +69 -84
- package/LICENSE +0 -661
- package/dist/amll-core.css +0 -2
- package/dist/amll-core.js.map +0 -1
- package/dist/bg-render/base.d.ts +0 -109
- package/dist/bg-render/img.d.ts +0 -4
- package/dist/bg-render/index.d.ts +0 -28
- package/dist/bg-render/mesh-renderer/cp-generate.d.ts +0 -6
- package/dist/bg-render/mesh-renderer/cp-presets.d.ts +0 -22
- package/dist/bg-render/mesh-renderer/index.d.ts +0 -76
- package/dist/bg-render/pixi-renderer.d.ts +0 -22
- package/dist/canvas-test.d.ts +0 -1
- package/dist/index.d.ts +0 -4
- package/dist/interfaces.d.ts +0 -106
- package/dist/lyric-player/base.d.ts +0 -327
- package/dist/lyric-player/bottom-line.d.ts +0 -29
- package/dist/lyric-player/canvas/index.d.ts +0 -24
- package/dist/lyric-player/canvas/lyric-line.d.ts +0 -24
- package/dist/lyric-player/canvas/text-layout.d.ts +0 -39
- package/dist/lyric-player/dom/index.d.ts +0 -59
- package/dist/lyric-player/dom/interlude-dots.d.ts +0 -22
- package/dist/lyric-player/dom/lyric-line.d.ts +0 -80
- package/dist/lyric-player/dom-slim/index.d.ts +0 -38
- package/dist/lyric-player/dom-slim/interlude-dots.d.ts +0 -22
- package/dist/lyric-player/dom-slim/lyric-line.d.ts +0 -69
- package/dist/lyric-player/index.d.ts +0 -29
- package/dist/mg-test.d.ts +0 -1
- package/dist/utils/debounce.d.ts +0 -2
- package/dist/utils/derivative.d.ts +0 -2
- package/dist/utils/eq-set.d.ts +0 -1
- package/dist/utils/flagsets.d.ts +0 -17
- package/dist/utils/is-cjk.d.ts +0 -1
- package/dist/utils/linear.d.ts +0 -21
- package/dist/utils/lyric-split-words.d.ts +0 -11
- package/dist/utils/matrix.d.ts +0 -25
- package/dist/utils/mutex.d.ts +0 -2
- package/dist/utils/optimize-lyric.d.ts +0 -9
- package/dist/utils/resource.d.ts +0 -4
- package/dist/utils/schedule.d.ts +0 -6
- package/dist/utils/spring.d.ts +0 -26
- package/dist/utils/wa-spring.d.ts +0 -27
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amll-core.mjs","names":["clamp","meshVertShader","meshFragShader","styles","styles","styles","ANIMATION_FRAME_QUANTITY","norNum","EMP_EASING_MID","beginNum","endNum","bezIn","bezOut","makeEmpEasing","generateFadeGradient","RawLyricLineMouseEvent","LyricLineEl","styles","styles","LyricLineEl","styles","styles"],"sources":["../src/bg-render/base.ts","../src/utils/resource.ts","../src/bg-render/img.ts","../src/bg-render/mesh-renderer/cp-presets.ts","../src/bg-render/mesh-renderer/cp-generate.ts","../src/bg-render/mesh-renderer/index.ts","../src/bg-render/pixi-renderer.ts","../src/bg-render/index.ts","../src/styles/lyric-player.module.css","../src/utils/eq-set.ts","../src/utils/is-cjk.ts","../src/utils/optimize-lyric.ts","../src/utils/derivative.ts","../src/utils/spring.ts","../src/utils/schedule.ts","../src/lyric-player/bottom-line.ts","../src/lyric-player/dom/interlude-dots.ts","../src/lyric-player/base.ts","../src/utils/lyric-split-words.ts","../src/utils/matrix.ts","../src/lyric-player/dom/lyric-line.ts","../src/lyric-player/dom/index.ts","../src/utils/debounce.ts","../src/lyric-player/dom-slim/index.module.css","../src/utils/mutex.ts","../src/lyric-player/dom-slim/lyric-line.ts","../src/lyric-player/dom-slim/index.ts","../src/lyric-player/index.ts"],"sourcesContent":["import type { Disposable, HasElement } from \"../interfaces.ts\";\n\nexport abstract class AbstractBaseRenderer implements Disposable, HasElement {\n\t/**\n\t * 修改背景的流动速度,数字越大越快,默认为 8\n\t * @param speed 背景的流动速度,默认为 8\n\t */\n\tabstract setFlowSpeed(speed: number): void;\n\t/**\n\t * 修改背景的渲染比例,默认是 0.5\n\t *\n\t * 一般情况下这个程度既没有明显瑕疵也不会特别吃性能\n\t * @param scale 背景的渲染比例\n\t */\n\tabstract setRenderScale(scale: number): void;\n\t/**\n\t * 是否启用静态模式,即图片在更换后就会保持静止状态并禁用更新,以节省性能\n\t * @param enable 是否启用静态模式\n\t */\n\tabstract setStaticMode(enable: boolean): void;\n\t/**\n\t * 修改背景动画帧率,默认是 30 FPS\n\t *\n\t * 如果设置成 0 则会停止动画\n\t * @param fps 目标帧率,默认 30 FPS\n\t */\n\tabstract setFPS(fps: number): void;\n\t/**\n\t * 暂停背景动画,画面即便是更新了图片也不会发生变化\n\t */\n\tabstract pause(): void;\n\t/**\n\t * 恢复播放背景动画\n\t */\n\tabstract resume(): void;\n\t/**\n\t * 设置背景专辑资源,纹理加载并设置完成后会返回\n\t * @param albumSource 专辑的资源链接,可以是图片或视频链接,抑或是任意 img/video 元素,如果提供字符串链接且为视频则需要指定第二个参数\n\t */\n\tabstract setAlbum(\n\t\talbumSource: string | HTMLImageElement | HTMLVideoElement,\n\t\tisVideo?: boolean,\n\t): Promise<void>;\n\t/**\n\t * 设置低频的音量大小,范围在 80hz-120hz 之间为宜,取值范围在 [0.0-1.0] 之间\n\t *\n\t * 部分渲染器会根据音量大小调整背景效果(例如根据鼓点跳动)\n\t *\n\t * 如果无法获取到类似的数据,请传入 1.0 作为默认值,或不做任何处理(默认值即 1.0)\n\t * @param volume 低频的音量大小,范围在 50hz-120hz 之间为宜,取值范围在 [0.0-1.0] 之间\n\t */\n\tabstract setLowFreqVolume(volume: number): void;\n\t/**\n\t * 设置背景是否根据“是否有歌词”这个特征调整自身效果,例如有歌词时会变得更加活跃\n\t *\n\t * 部分渲染器会根据这个特征调整自身效果\n\t *\n\t * 如果不确定是否需要赋值或无法知晓是否包含歌词,请传入 true 或不做任何处理(默认值为 true)\n\t *\n\t * @param hasLyric 是否有歌词,如不确定是否需要赋值,请传入 true 或不做任何处理(默认值为 true)\n\t */\n\tabstract setHasLyric(hasLyric: boolean): void;\n\tabstract dispose(): void;\n\tabstract getElement(): HTMLElement;\n}\n\nexport abstract class BaseRenderer extends AbstractBaseRenderer {\n\tprivate observer: ResizeObserver;\n\tprotected flowSpeed = 1;\n\tprotected currerntRenderScale = 0.75;\n\tconstructor(protected canvas: HTMLCanvasElement) {\n\t\tsuper();\n\t\tthis.observer = new ResizeObserver(() => {\n\t\t\tconst width = Math.max(\n\t\t\t\t1,\n\t\t\t\tcanvas.clientWidth * window.devicePixelRatio * this.currerntRenderScale,\n\t\t\t);\n\t\t\tconst height = Math.max(\n\t\t\t\t1,\n\t\t\t\tcanvas.clientHeight *\n\t\t\t\t\twindow.devicePixelRatio *\n\t\t\t\t\tthis.currerntRenderScale,\n\t\t\t);\n\t\t\tthis.onResize(width, height);\n\t\t});\n\t\tthis.observer.observe(canvas);\n\t}\n\tsetRenderScale(scale: number): void {\n\t\tthis.currerntRenderScale = scale;\n\t\tthis.onResize(\n\t\t\tthis.canvas.clientWidth *\n\t\t\t\twindow.devicePixelRatio *\n\t\t\t\tthis.currerntRenderScale,\n\t\t\tthis.canvas.clientHeight *\n\t\t\t\twindow.devicePixelRatio *\n\t\t\t\tthis.currerntRenderScale,\n\t\t);\n\t}\n\t/**\n\t * 当画板元素大小发生变化时此函数会被调用\n\t * 可以在此处重设和渲染器相关的尺寸设置\n\t * 考虑到初始化的时候元素不一定在文档中或出于某些特殊样式状态,尺寸长宽有可能会为 0,请注意进行特判处理\n\t * @param width 画板元素实际的物理像素宽度,有可能为 0\n\t * @param height 画板元素实际的物理像素高度,有可能为 0\n\t */\n\tprotected onResize(width: number, height: number): void {\n\t\tthis.canvas.width = width;\n\t\tthis.canvas.height = height;\n\t}\n\t/**\n\t * 修改背景的流动速度,数字越大越快,默认为 1\n\t * @param speed 背景的流动速度,默认为 1\n\t */\n\tsetFlowSpeed(speed: number): void {\n\t\tthis.flowSpeed = speed;\n\t}\n\t/**\n\t * 是否启用静态模式,即图片在更换后就会保持静止状态并禁用更新,以节省性能\n\t * @param enable 是否启用静态模式\n\t */\n\tabstract override setStaticMode(enable: boolean): void;\n\t/**\n\t * 修改背景动画帧率,默认是 30 FPS\n\t *\n\t * 如果设置成 0 则会停止动画\n\t * @param fps 目标帧率,默认 30 FPS\n\t */\n\tabstract override setFPS(fps: number): void;\n\t/**\n\t * 暂停背景动画,画面即便是更新了图片也不会发生变化\n\t */\n\tabstract override pause(): void;\n\t/**\n\t * 恢复播放背景动画\n\t */\n\tabstract override resume(): void;\n\t/**\n\t * 设置背景专辑资源,纹理加载并设置完成后会返回\n\t * @param albumSource 专辑的资源链接,可以是图片或视频链接,抑或是任意 img/video 元素,如果提供字符串链接且为视频则需要指定第二个参数\n\t */\n\tabstract override setAlbum(\n\t\talbumSource: string | HTMLImageElement | HTMLVideoElement,\n\t\tisVideo?: boolean,\n\t): Promise<void>;\n\tdispose(): void {\n\t\tthis.observer.disconnect();\n\t\tthis.canvas.remove();\n\t}\n\toverride getElement(): HTMLElement {\n\t\treturn this.canvas;\n\t}\n}\n","export function loadImage(imageUrl: string): Promise<HTMLImageElement> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst img = document.createElement(\"img\");\n\t\timg.onload = () => resolve(img);\n\t\timg.onerror = reject;\n\t\timg.src = imageUrl;\n\t\timg.crossOrigin = \"anonymous\";\n\t\timg.loading = \"eager\";\n\t});\n}\n\nexport function loadVideo(videoUrl: string): Promise<HTMLVideoElement> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst video = document.createElement(\"video\");\n\t\tlet playing = false;\n\t\tlet timeupdate = false;\n\t\tlet rejected = false;\n\t\tvideo.addEventListener(\n\t\t\t\"playing\",\n\t\t\t() => {\n\t\t\t\tplaying = true;\n\t\t\t\tcheckReady();\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\t\tvideo.addEventListener(\n\t\t\t\"timeupdate\",\n\t\t\t() => {\n\t\t\t\ttimeupdate = true;\n\t\t\t\tcheckReady();\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\t\tvideo.addEventListener(\n\t\t\t\"error\",\n\t\t\t(err) => {\n\t\t\t\trejected = true;\n\t\t\t\treject(err);\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\t\tfunction checkReady() {\n\t\t\tif (playing && timeupdate && !rejected) {\n\t\t\t\tresolve(video);\n\t\t\t}\n\t\t}\n\t\tvideo.src = videoUrl;\n\t\tvideo.playsInline = true;\n\t\tvideo.crossOrigin = \"anonymous\";\n\t\tvideo.autoplay = true;\n\t\tvideo.loop = true;\n\t\tvideo.muted = true;\n\t\tvideo.play();\n\t});\n}\n\nexport function loadResourceFromUrl(\n\turl: string,\n\tisVideo = false,\n): Promise<HTMLImageElement | HTMLVideoElement> {\n\treturn isVideo ? loadVideo(url) : loadImage(url);\n}\n\nexport function loadResourceFromElement(\n\telement: HTMLImageElement | HTMLVideoElement,\n): Promise<HTMLImageElement | HTMLVideoElement> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (\n\t\t\telement instanceof HTMLImageElement\n\t\t\t\t? element.complete\n\t\t\t\t: element.readyState >= 3\n\t\t) {\n\t\t\tresolve(element);\n\t\t} else {\n\t\t\telement.onload = () => resolve(element);\n\t\t\telement.onerror = reject;\n\t\t}\n\t});\n}\n","export function blurImage(\n\timageData: ImageData,\n\tradius: number,\n\tquality: number,\n): void {\n\tconst pixels = imageData.data;\n\tconst width = imageData.width;\n\tconst height = imageData.height;\n\n\tlet rsum: number;\n\tlet gsum: number;\n\tlet bsum: number;\n\tlet asum: number;\n\tlet x: number;\n\tlet y: number;\n\tlet i: number;\n\tlet p: number;\n\tlet p1: number;\n\tlet p2: number;\n\tlet yp: number;\n\tlet yi: number;\n\tlet yw: number;\n\tconst wm = width - 1;\n\tconst hm = height - 1;\n\tconst rad1x = radius + 1;\n\tconst divx = radius + rad1x;\n\tconst rad1y = radius + 1;\n\tconst divy = radius + rad1y;\n\tconst div2 = 1 / (divx * divy);\n\n\tconst r: number[] = [];\n\tconst g: number[] = [];\n\tconst b: number[] = [];\n\tconst a: number[] = [];\n\n\tconst vmin: number[] = [];\n\tconst vmax: number[] = [];\n\n\twhile (quality-- > 0) {\n\t\tyw = yi = 0;\n\n\t\tfor (y = 0; y < height; y++) {\n\t\t\trsum = pixels[yw] * rad1x;\n\t\t\tgsum = pixels[yw + 1] * rad1x;\n\t\t\tbsum = pixels[yw + 2] * rad1x;\n\t\t\tasum = pixels[yw + 3] * rad1x;\n\n\t\t\tfor (i = 1; i <= radius; i++) {\n\t\t\t\tp = yw + ((i > wm ? wm : i) << 2);\n\t\t\t\trsum += pixels[p++];\n\t\t\t\tgsum += pixels[p++];\n\t\t\t\tbsum += pixels[p++];\n\t\t\t\tasum += pixels[p];\n\t\t\t}\n\n\t\t\tfor (x = 0; x < width; x++) {\n\t\t\t\tr[yi] = rsum;\n\t\t\t\tg[yi] = gsum;\n\t\t\t\tb[yi] = bsum;\n\t\t\t\ta[yi] = asum;\n\n\t\t\t\tif (y === 0) {\n\t\t\t\t\tvmin[x] = Math.min(x + rad1x, wm) << 2;\n\t\t\t\t\tvmax[x] = Math.max(x - radius, 0) << 2;\n\t\t\t\t}\n\n\t\t\t\tp1 = yw + vmin[x];\n\t\t\t\tp2 = yw + vmax[x];\n\n\t\t\t\trsum += pixels[p1++] - pixels[p2++];\n\t\t\t\tgsum += pixels[p1++] - pixels[p2++];\n\t\t\t\tbsum += pixels[p1++] - pixels[p2++];\n\t\t\t\tasum += pixels[p1] - pixels[p2];\n\n\t\t\t\tyi++;\n\t\t\t}\n\t\t\tyw += width << 2;\n\t\t}\n\n\t\tfor (x = 0; x < width; x++) {\n\t\t\typ = x;\n\t\t\trsum = r[yp] * rad1y;\n\t\t\tgsum = g[yp] * rad1y;\n\t\t\tbsum = b[yp] * rad1y;\n\t\t\tasum = a[yp] * rad1y;\n\n\t\t\tfor (i = 1; i <= radius; i++) {\n\t\t\t\typ += i > hm ? 0 : width;\n\t\t\t\trsum += r[yp];\n\t\t\t\tgsum += g[yp];\n\t\t\t\tbsum += b[yp];\n\t\t\t\tasum += a[yp];\n\t\t\t}\n\n\t\t\tyi = x << 2;\n\t\t\tfor (y = 0; y < height; y++) {\n\t\t\t\tpixels[yi] = (rsum * div2 + 0.5) | 0;\n\t\t\t\tpixels[yi + 1] = (gsum * div2 + 0.5) | 0;\n\t\t\t\tpixels[yi + 2] = (bsum * div2 + 0.5) | 0;\n\t\t\t\tpixels[yi + 3] = (asum * div2 + 0.5) | 0;\n\n\t\t\t\tif (x === 0) {\n\t\t\t\t\tvmin[y] = Math.min(y + rad1y, hm) * width;\n\t\t\t\t\tvmax[y] = Math.max(y - radius, 0) * width;\n\t\t\t\t}\n\n\t\t\t\tp1 = x + vmin[y];\n\t\t\t\tp2 = x + vmax[y];\n\n\t\t\t\trsum += r[p1] - r[p2];\n\t\t\t\tgsum += g[p1] - g[p2];\n\t\t\t\tbsum += b[p1] - b[p2];\n\t\t\t\tasum += a[p1] - a[p2];\n\n\t\t\t\tyi += width << 2;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function saturateImage(imageData: ImageData, saturation: number): void {\n\tconst pixels = imageData.data;\n\n\tfor (let i = 0; i < pixels.length; i += 4) {\n\t\tconst r = pixels[i];\n\t\tconst g = pixels[i + 1];\n\t\tconst b = pixels[i + 2];\n\t\tconst a = pixels[i + 3];\n\t\tconst gray = r * 0.3 + g * 0.59 + b * 0.11;\n\t\tpixels[i] = gray * (1 - saturation) + r * saturation;\n\t\tpixels[i + 1] = gray * (1 - saturation) + g * saturation;\n\t\tpixels[i + 2] = gray * (1 - saturation) + b * saturation;\n\t\tpixels[i + 3] = a;\n\t}\n}\n\nexport function brightnessImage(\n\timageData: ImageData,\n\tbrightness: number,\n): void {\n\tconst pixels = imageData.data;\n\n\tfor (let i = 0; i < pixels.length; i += 4) {\n\t\tconst r = pixels[i];\n\t\tconst g = pixels[i + 1];\n\t\tconst b = pixels[i + 2];\n\t\tconst a = pixels[i + 3];\n\t\tpixels[i] = r * brightness;\n\t\tpixels[i + 1] = g * brightness;\n\t\tpixels[i + 2] = b * brightness;\n\t\tpixels[i + 3] = a;\n\t}\n}\n\nexport function contrastImage(imageData: ImageData, contrast: number): void {\n\tconst pixels = imageData.data;\n\n\tfor (let i = 0; i < pixels.length; i += 4) {\n\t\tconst r = pixels[i];\n\t\tconst g = pixels[i + 1];\n\t\tconst b = pixels[i + 2];\n\t\tconst a = pixels[i + 3];\n\t\tpixels[i] = (r - 128) * contrast + 128;\n\t\tpixels[i + 1] = (g - 128) * contrast + 128;\n\t\tpixels[i + 2] = (b - 128) * contrast + 128;\n\t\tpixels[i + 3] = a;\n\t}\n}\n","/** @internal */\nexport interface ControlPointConf {\n\tcx: number;\n\tcy: number;\n\tx: number;\n\ty: number;\n\tur: number;\n\tvr: number;\n\tup: number;\n\tvp: number;\n}\n\n/** @internal */\nexport interface ControlPointPreset {\n\twidth: number;\n\theight: number;\n\tconf: ControlPointConf[];\n}\n\n/** @internal */\nexport const p = (\n\tcx: number,\n\tcy: number,\n\tx: number,\n\ty: number,\n\tur = 0,\n\tvr = 0,\n\tup = 1,\n\tvp = 1,\n) => Object.freeze({ cx, cy, x, y, ur, vr, up, vp }) as ControlPointConf;\n/** @internal */\nexport const preset = (\n\twidth: number,\n\theight: number,\n\tconf: ControlPointConf[],\n) => Object.freeze({ width, height, conf }) as ControlPointPreset;\n\nexport const CONTROL_POINT_PRESETS: ControlPointPreset[] = [\n\t// TODO: 竖屏推荐\n\tpreset(5, 5, [\n\t\tp(0, 0, -1, -1, 0, 0, 1, 1),\n\t\tp(1, 0, -0.5, -1, 0, 0, 1, 1),\n\t\tp(2, 0, 0, -1, 0, 0, 1, 1),\n\t\tp(3, 0, 0.5, -1, 0, 0, 1, 1),\n\t\tp(4, 0, 1, -1, 0, 0, 1, 1),\n\t\tp(0, 1, -1, -0.5, 0, 0, 1, 1),\n\t\tp(1, 1, -0.5, -0.5, 0, 0, 1, 1),\n\t\tp(2, 1, -0.0052029684413368305, -0.6131420587090777, 0, 0, 1, 1),\n\t\tp(3, 1, 0.5884227308309977, -0.3990805107556692, 0, 0, 1, 1),\n\t\tp(4, 1, 1, -0.5, 0, 0, 1, 1),\n\t\tp(0, 2, -1, 0, 0, 0, 1, 1),\n\t\tp(1, 2, -0.4210024670505933, -0.11895058380429502, 0, 0, 1, 1),\n\t\tp(2, 2, -0.1019613423315412, -0.023812118047224606, 0, -47, 0.629, 0.849),\n\t\tp(3, 2, 0.40275125660925437, -0.06345314544600389, 0, 0, 1, 1),\n\t\tp(4, 2, 1, 0, 0, 0, 1, 1),\n\t\tp(0, 3, -1, 0.5, 0, 0, 1, 1),\n\t\tp(1, 3, 0.06801958477287173, 0.5205913248960121, -31, -45, 1, 1),\n\t\tp(2, 3, 0.21446469120128908, 0.29331610114301043, 6, -56, 0.566, 1.321),\n\t\tp(3, 3, 0.5, 0.5, 0, 0, 1, 1),\n\t\tp(4, 3, 1, 0.5, 0, 0, 1, 1),\n\t\tp(0, 4, -1, 1, 0, 0, 1, 1),\n\t\tp(1, 4, -0.31378372841550195, 1, 0, 0, 1, 1),\n\t\tp(2, 4, 0.26153633255328046, 1, 0, 0, 1, 1),\n\t\tp(3, 4, 0.5, 1, 0, 0, 1, 1),\n\t\tp(4, 4, 1, 1, 0, 0, 1, 1),\n\t]),\n\t// TODO: 横屏推荐\n\tpreset(4, 4, [\n\t\tp(0, 0, -1, -1, 0, 0, 1, 1),\n\t\tp(1, 0, -0.33333333333333337, -1, 0, 0, 1, 1),\n\t\tp(2, 0, 0.33333333333333326, -1, 0, 0, 1, 1),\n\t\tp(3, 0, 1, -1, 0, 0, 1, 1),\n\t\tp(0, 1, -1, -0.04495399932657351, 0, 0, 1, 1),\n\t\tp(1, 1, -0.24056117520129328, -0.22465999020104, 0, 0, 1, 1),\n\t\tp(2, 1, 0.334758885767489, -0.00531297192779423, 0, 0, 1, 1),\n\t\tp(3, 1, 0.9989920470678106, -0.3382976020775408, 8, 0, 0.566, 1.792),\n\t\tp(0, 2, -1, 0.33333333333333326, 0, 0, 1, 1),\n\t\tp(1, 2, -0.3425497314639411, -0.000027501607956947893, 0, 0, 1, 1),\n\t\tp(2, 2, 0.3321437945812673, 0.1981776353859399, 0, 0, 1, 1),\n\t\tp(3, 2, 1, 0.0766118180296832, 0, 0, 1, 1),\n\t\tp(0, 3, -1, 1, 0, 0, 1, 1),\n\t\tp(1, 3, -0.33333333333333337, 1, 0, 0, 1, 1),\n\t\tp(2, 3, 0.33333333333333326, 1, 0, 0, 1, 1),\n\t\tp(3, 3, 1, 1, 0, 0, 1, 1),\n\t]),\n\tpreset(4, 4, [\n\t\tp(0, 0, -1, -1, 0, 0, 1, 2.075),\n\t\tp(1, 0, -0.33333333333333337, -1, 0, 0, 1, 1),\n\t\tp(2, 0, 0.33333333333333326, -1, 0, 0, 1, 1),\n\t\tp(3, 0, 1, -1, 0, 0, 1, 1),\n\t\tp(0, 1, -1, -0.4545779491139603, 0, 0, 1, 1),\n\t\tp(1, 1, -0.33333333333333337, -0.33333333333333337, 0, 0, 1, 1),\n\t\tp(2, 1, 0.0889403142626457, -0.6025711180694033, -32, 45, 1, 1),\n\t\tp(3, 1, 1, -0.33333333333333337, 0, 0, 1, 1),\n\t\tp(0, 2, -1, -0.07402408608567845, 1, 0, 1, 0.094),\n\t\tp(1, 2, -0.2719422694359541, 0.09775369930903222, 25, -18, 1.321, 0),\n\t\tp(2, 2, 0.19877414408395877, 0.4307383294587789, 48, -40, 0.755, 0.975),\n\t\tp(3, 2, 1, 0.33333333333333326, -37, 0, 1, 1),\n\t\tp(0, 3, -1, 1, 0, 0, 1, 1),\n\t\tp(1, 3, -0.33333333333333337, 1, 0, 0, 1, 1),\n\t\tp(2, 3, 0.5125850864305672, 1, -20, -18, 0, 1.604),\n\t\tp(3, 3, 1, 1, 0, 0, 1, 1),\n\t]),\n\tpreset(5, 5, [\n\t\tp(0, 0, -1, -1, 0, 0, 1, 1),\n\t\tp(1, 0, -0.4501953125, -1, 0, 55, 1, 2.075),\n\t\tp(2, 0, 0.1953125, -1, 0, 0, 1, 1),\n\t\tp(3, 0, 0.4580078125, -1, 0, -25, 1, 1),\n\t\tp(4, 0, 1, -1, 0, 0, 1, 1),\n\t\tp(0, 1, -1, -0.2514475377525607, -16, 0, 2.327, 0.943),\n\t\tp(1, 1, -0.55859375, -0.6609325945787148, 47, 0, 2.358, 0.377),\n\t\tp(2, 1, 0.232421875, -0.5244375756366635, -66, -25, 1.855, 1.164),\n\t\tp(3, 1, 0.685546875, -0.3753706470552125, 0, 0, 1, 1),\n\t\tp(4, 1, 1, -0.6699125300354287, 0, 0, 1, 1),\n\t\tp(0, 2, -1, 0.035910396862284255, 0, 0, 1, 1),\n\t\tp(1, 2, -0.4921875, 0.005378616309457018, 90, 23, 1, 1.981),\n\t\tp(2, 2, 0.021484375, -0.1365043639066228, 0, 42, 1, 1),\n\t\tp(3, 2, 0.4765625, 0.05925822904974043, -30, 0, 1.95, 0.44),\n\t\tp(4, 2, 1, 0.251428847823418, 0, 0, 1, 1),\n\t\tp(0, 3, -1, 0.6968336464764276, -68, 0, 1, 0.786),\n\t\tp(1, 3, -0.6904296875, 0.5890744209958608, -68, 0, 1, 1),\n\t\tp(2, 3, 0.1845703125, 0.3879238667654693, 61, 0, 1, 1),\n\t\tp(3, 3, 0.60546875, 0.4633553246018661, -47, -59, 0.849, 1.73),\n\t\tp(4, 3, 1, 0.6214021886400309, -33, 0, 0.377, 1.604),\n\t\tp(0, 4, -1, 1, 0, 0, 1, 1),\n\t\tp(1, 4, -0.5, 1, 0, -73, 1, 1),\n\t\tp(2, 4, -0.3271484375, 1, 0, -24, 0.314, 2.704),\n\t\tp(3, 4, 0.5, 1, 0, 0, 1, 1),\n\t\tp(4, 4, 1, 1, 0, 0, 1, 1),\n\t]),\n\tpreset(5, 5, [\n\t\tp(0, 0, -1, -1),\n\t\tp(1, 0, -0.6393, -1, 0, 0, 1, 2.3884),\n\t\tp(2, 0, 0, -1),\n\t\tp(3, 0, 0.5, -1),\n\t\tp(4, 0, 1, -1),\n\t\tp(0, 1, -1, -0.2301),\n\t\tp(1, 1, -0.6934, -0.331, 0, -0.7188, 1, 1.063),\n\t\tp(2, 1, -0.0082, -0.6814, -0.2583, 0, 1.0964, 1),\n\t\tp(3, 1, 0.5836, -0.531, 0.7029, 0, 1.5466, 1),\n\t\tp(4, 1, 1, -0.6407),\n\t\tp(0, 2, -1, 0.2973, 0, 0, 1.8352, 1),\n\t\tp(1, 2, -0.4082, 0.0602),\n\t\tp(2, 2, -0.1803, -0.3646, -0.2998, 0, 1.1513, 1),\n\t\tp(3, 2, 0.477, -0.1027, 0.8903, -0.1882, 1.0807, 0.8551),\n\t\tp(4, 2, 1, -0.2973),\n\t\tp(0, 3, -1, 0.7628, 0, 0, 2.3868, 1),\n\t\tp(1, 3, -0.2525, 0.4814, -0.8406, -1.6199, 1.4093, 1.2215),\n\t\tp(2, 3, 0.3607, 0.2814, -1.0713, -0.0529, 1.0025, 0.7611),\n\t\tp(3, 3, 0.4885, 0.623, 0, 0.8184, 1, 1.2876),\n\t\tp(4, 3, 1, 0.5),\n\t\tp(0, 4, -1, 1),\n\t\tp(1, 4, -0.4033, 1),\n\t\tp(2, 4, 0.2672, 1),\n\t\tp(3, 4, 0.5967, 1),\n\t\tp(4, 4, 1, 1),\n\t]),\n\tpreset(5, 5, [\n\t\tp(0, 0, -1, -1),\n\t\tp(1, 0, -0.2197, -1),\n\t\tp(2, 0, 0.0197, -1),\n\t\tp(3, 0, 0.8033, -1),\n\t\tp(4, 0, 1, -1),\n\t\tp(0, 1, -1, -0.5451),\n\t\tp(1, 1, -0.4885, -0.4035, -1.0246, -0.2268, 1.1936, 0.8005),\n\t\tp(2, 1, -0.1213, -0.2867, 0, -0.6981, 1, 0.809),\n\t\tp(3, 1, 0.3246, -0.5628, 0, -1.2188, 1, 1.044),\n\t\tp(4, 1, 1, -0.3292),\n\t\tp(0, 2, -1, 0.1416),\n\t\tp(1, 2, -0.341, -0.0142, 0, -0.4004, 1, 1.1293),\n\t\tp(2, 2, -0.0393, -0.023, 0.2915, -0.373, 1.044, 0.9879),\n\t\tp(3, 2, 0.3148, -0.0673, -0.7853, -0.8962, 1.4709, 1.0247),\n\t\tp(4, 2, 1, 0.1912),\n\t\tp(0, 3, -1, 0.5),\n\t\tp(1, 3, -0.2689, 0.2743, 0.3404, -0.5248, 1.0184, 0.4391),\n\t\tp(2, 3, 0.0721, 0.269, 0.5302, 0.1244, 0.6723, 0.3225),\n\t\tp(3, 3, 0.4148, 0.3894, -0.6977, -0.6783, 0.8094, 0.9247),\n\t\tp(4, 3, 1, 0.446),\n\t\tp(0, 4, -1, 1),\n\t\tp(1, 4, -0.7311, 1),\n\t\tp(2, 4, 0.323, 1),\n\t\tp(3, 4, 0.6393, 1),\n\t\tp(4, 4, 1, 1),\n\t]),\n] as const;\n","/**\n * @fileoverview\n * 实验性的随机控制点生成函数算法\n * 目的是取代原先大量的预设控制点代码\n */\n\nimport {\n\ttype ControlPointConf,\n\ttype ControlPointPreset,\n\tp,\n\tpreset,\n} from \"./cp-presets.ts\";\n\nconst randomRange = (min: number, max: number): number =>\n\tMath.random() * (max - min) + min;\n\nfunction clamp(x: number, min: number, max: number): number {\n\treturn Math.min(Math.max(x, min), max);\n}\n\nfunction smoothstep(edge0: number, edge1: number, x: number): number {\n\tconst t = clamp((x - edge0) / (edge1 - edge0), 0, 1);\n\treturn t * t * (3 - 2 * t);\n}\n\nfunction smoothifyControlPoints(\n\tconf: ControlPointConf[],\n\tw: number,\n\th: number,\n\titerations = 2,\n\tfactor = 0.5,\n\tfactorIterationModifier = 0.1,\n): void {\n\tlet grid: ControlPointConf[][] = [];\n\tlet f = factor;\n\n\tfor (let j = 0; j < h; j++) {\n\t\tgrid[j] = [];\n\t\tfor (let i = 0; i < w; i++) {\n\t\t\tgrid[j][i] = conf[j * w + i];\n\t\t}\n\t}\n\n\tconst kernel = [\n\t\t[1, 2, 1],\n\t\t[2, 4, 2],\n\t\t[1, 2, 1],\n\t];\n\tconst kernelSum = 16;\n\n\tfor (let iter = 0; iter < iterations; iter++) {\n\t\tconst newGrid: ControlPointConf[][] = [];\n\t\tfor (let j = 0; j < h; j++) {\n\t\t\tnewGrid[j] = [];\n\t\t\tfor (let i = 0; i < w; i++) {\n\t\t\t\tif (i === 0 || i === w - 1 || j === 0 || j === h - 1) {\n\t\t\t\t\tnewGrid[j][i] = grid[j][i];\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tlet sumX = 0;\n\t\t\t\tlet sumY = 0;\n\t\t\t\tlet sumUR = 0;\n\t\t\t\tlet sumVR = 0;\n\t\t\t\tlet sumUP = 0;\n\t\t\t\tlet sumVP = 0;\n\t\t\t\tfor (let dj = -1; dj <= 1; dj++) {\n\t\t\t\t\tfor (let di = -1; di <= 1; di++) {\n\t\t\t\t\t\tconst weight = kernel[dj + 1][di + 1];\n\t\t\t\t\t\tconst nb = grid[j + dj][i + di];\n\t\t\t\t\t\tsumX += nb.x * weight;\n\t\t\t\t\t\tsumY += nb.y * weight;\n\t\t\t\t\t\tsumUR += nb.ur * weight;\n\t\t\t\t\t\tsumVR += nb.vr * weight;\n\t\t\t\t\t\tsumUP += nb.up * weight;\n\t\t\t\t\t\tsumVP += nb.vp * weight;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst avgX = sumX / kernelSum;\n\t\t\t\tconst avgY = sumY / kernelSum;\n\t\t\t\tconst avgUR = sumUR / kernelSum;\n\t\t\t\tconst avgVR = sumVR / kernelSum;\n\t\t\t\tconst avgUP = sumUP / kernelSum;\n\t\t\t\tconst avgVP = sumVP / kernelSum;\n\n\t\t\t\tconst cur = grid[j][i];\n\t\t\t\tconst newX = cur.x * (1 - f) + avgX * f;\n\t\t\t\tconst newY = cur.y * (1 - f) + avgY * f;\n\t\t\t\tconst newUR = cur.ur * (1 - f) + avgUR * f;\n\t\t\t\tconst newVR = cur.vr * (1 - f) + avgVR * f;\n\t\t\t\tconst newUP = cur.up * (1 - f) + avgUP * f;\n\t\t\t\tconst newVP = cur.vp * (1 - f) + avgVP * f;\n\t\t\t\tnewGrid[j][i] = p(i, j, newX, newY, newUR, newVR, newUP, newVP);\n\t\t\t}\n\t\t}\n\t\tgrid = newGrid;\n\t\tf = Math.min(1, Math.max(f + factorIterationModifier, 0));\n\t}\n\n\tfor (let j = 0; j < h; j++) {\n\t\tfor (let i = 0; i < w; i++) {\n\t\t\tconf[j * w + i] = grid[j][i];\n\t\t}\n\t}\n}\n\nfunction noise(x: number, y: number): number {\n\treturn fract(Math.sin(x * 12.9898 + y * 78.233) * 43758.5453);\n}\n\nfunction fract(x: number): number {\n\treturn x - Math.floor(x);\n}\n\nfunction smoothNoise(x: number, y: number): number {\n\tconst x0 = Math.floor(x);\n\tconst y0 = Math.floor(y);\n\tconst x1 = x0 + 1;\n\tconst y1 = y0 + 1;\n\n\tconst xf = x - x0;\n\tconst yf = y - y0;\n\n\tconst u = xf * xf * (3 - 2 * xf);\n\tconst v = yf * yf * (3 - 2 * yf);\n\n\tconst n00 = noise(x0, y0);\n\tconst n10 = noise(x1, y0);\n\tconst n01 = noise(x0, y1);\n\tconst n11 = noise(x1, y1);\n\n\tconst nx0 = n00 * (1 - u) + n10 * u;\n\tconst nx1 = n01 * (1 - u) + n11 * u;\n\n\treturn nx0 * (1 - v) + nx1 * v;\n}\n\nfunction computeNoiseGradient(\n\tperlinFn: (x: number, y: number) => number,\n\tx: number,\n\ty: number,\n\tepsilon = 0.001,\n): [number, number] {\n\tconst n1 = perlinFn(x + epsilon, y);\n\tconst n2 = perlinFn(x - epsilon, y);\n\tconst n3 = perlinFn(x, y + epsilon);\n\tconst n4 = perlinFn(x, y - epsilon);\n\tconst dx = (n1 - n2) / (2 * epsilon);\n\tconst dy = (n3 - n4) / (2 * epsilon);\n\tconst len = Math.sqrt(dx * dx + dy * dy) || 1;\n\treturn [dx / len, dy / len];\n}\n\nexport function generateControlPoints(\n\twidth: number,\n\theight: number,\n\tvariationFraction: number = randomRange(0.4, 0.6), // = 0.2,\n\tnormalOffset: number = randomRange(0.3, 0.6), // = 0.3,\n\tblendFactor = 0.8,\n\tsmoothIters: number = Math.floor(randomRange(3, 5)), // = 3,\n\tsmoothFactor: number = randomRange(0.2, 0.3), // = 0.3,\n\tsmoothModifier: number = randomRange(-0.1, -0.05), // = -0.05,\n): ControlPointPreset {\n\tconst w = width ?? Math.floor(randomRange(3, 6));\n\tconst h = height ?? Math.floor(randomRange(3, 6));\n\n\tconst conf: ControlPointConf[] = [];\n\tconst dx = w === 1 ? 0 : 2 / (w - 1);\n\tconst dy = h === 1 ? 0 : 2 / (h - 1);\n\n\tfor (let j = 0; j < h; j++) {\n\t\tfor (let i = 0; i < w; i++) {\n\t\t\tconst baseX = (w === 1 ? 0 : i / (w - 1)) * 2 - 1;\n\t\t\tconst baseY = (h === 1 ? 0 : j / (h - 1)) * 2 - 1;\n\n\t\t\tconst isBorder = i === 0 || i === w - 1 || j === 0 || j === h - 1;\n\t\t\tconst pertX = isBorder\n\t\t\t\t? 0\n\t\t\t\t: randomRange(-variationFraction * dx, variationFraction * dx);\n\t\t\tconst pertY = isBorder\n\t\t\t\t? 0\n\t\t\t\t: randomRange(-variationFraction * dy, variationFraction * dy);\n\t\t\tlet x = baseX + pertX;\n\t\t\tlet y = baseY + pertY;\n\n\t\t\tconst ur = isBorder ? 0 : randomRange(-60, 60);\n\t\t\tconst vr = isBorder ? 0 : randomRange(-60, 60);\n\t\t\tconst up = isBorder ? 1 : randomRange(0.8, 1.2);\n\t\t\tconst vp = isBorder ? 1 : randomRange(0.8, 1.2);\n\n\t\t\tif (!isBorder) {\n\t\t\t\tconst uNorm = (baseX + 1) / 2;\n\t\t\t\tconst vNorm = (baseY + 1) / 2;\n\n\t\t\t\tconst [nx, ny] = computeNoiseGradient(smoothNoise, uNorm, vNorm, 0.001);\n\t\t\t\tlet offsetX = nx * normalOffset;\n\t\t\t\tlet offsetY = ny * normalOffset;\n\n\t\t\t\tconst distToBorder = Math.min(uNorm, 1 - uNorm, vNorm, 1 - vNorm); // in [0,0.5]\n\n\t\t\t\tconst weight = smoothstep(0, 1.0, distToBorder);\n\t\t\t\toffsetX *= weight;\n\t\t\t\toffsetY *= weight;\n\n\t\t\t\tx = x * (1 - blendFactor) + (x + offsetX) * blendFactor;\n\t\t\t\ty = y * (1 - blendFactor) + (y + offsetY) * blendFactor;\n\t\t\t}\n\t\t\tconf.push(p(i, j, x, y, ur, vr, up, vp));\n\t\t}\n\t}\n\n\tsmoothifyControlPoints(conf, w, h, smoothIters, smoothFactor, smoothModifier);\n\n\treturn preset(w, h, conf);\n}\n","/**\n * @fileoverview\n * 基于 Mesh Gradient 渐变渲染的渲染器\n * 此渲染应该是 Apple Music 使用的背景渲染方式了\n * 参考内容 https://movingparts.io/gradient-meshes\n */\n\nimport { Mat4, Vec2, Vec3, Vec4 } from \"gl-matrix\";\nimport type { Disposable } from \"../../interfaces.ts\";\nimport {\n\tloadResourceFromElement,\n\tloadResourceFromUrl,\n} from \"../../utils/resource.ts\";\nimport { BaseRenderer } from \"../base.ts\";\nimport { blurImage } from \"../img.ts\";\nimport { generateControlPoints } from \"./cp-generate.ts\";\nimport { CONTROL_POINT_PRESETS } from \"./cp-presets.ts\";\nimport meshFragShader from \"./mesh.frag.glsl?raw\";\nimport meshVertShader from \"./mesh.vert.glsl?raw\";\n\nconst quadVertShader = `\nattribute vec2 a_pos;\nvarying vec2 v_uv;\nvoid main() {\n gl_Position = vec4(a_pos, 0.0, 1.0);\n v_uv = a_pos * 0.5 + 0.5;\n}\n`;\n\nconst quadFragShader = `\nprecision mediump float;\nvarying vec2 v_uv;\nuniform sampler2D u_texture;\nuniform float u_alpha;\nvoid main() {\n vec4 color = texture2D(u_texture, v_uv);\n gl_FragColor = vec4(color.rgb, color.a * u_alpha);\n}\n`;\n\nfunction easeInOutSine(x: number): number {\n\treturn -(Math.cos(Math.PI * x) - 1) / 2;\n}\n\ntype RenderingContext = WebGLRenderingContext;\n\nclass GLProgram implements Disposable {\n\tprivate gl: RenderingContext;\n\tprogram: WebGLProgram;\n\tprivate vertexShader: WebGLShader;\n\tprivate fragmentShader: WebGLShader;\n\treadonly attrs: { [name: string]: number };\n\tconstructor(\n\t\tgl: RenderingContext,\n\t\tvertexShaderSource: string,\n\t\tfragmentShaderSource: string,\n\t\tprivate readonly label = \"unknown\",\n\t) {\n\t\tthis.gl = gl;\n\t\tthis.vertexShader = this.createShader(gl.VERTEX_SHADER, vertexShaderSource);\n\t\tthis.fragmentShader = this.createShader(\n\t\t\tgl.FRAGMENT_SHADER,\n\t\t\tfragmentShaderSource,\n\t\t);\n\t\tthis.program = this.createProgram();\n\n\t\tconst num = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\n\t\tconst attrs: { [name: string]: number } = {};\n\t\tfor (let i = 0; i < num; i++) {\n\t\t\tconst info = gl.getActiveAttrib(this.program, i);\n\t\t\tif (!info) continue;\n\t\t\tconst location = gl.getAttribLocation(this.program, info.name);\n\t\t\tif (location === -1) continue;\n\t\t\tattrs[info.name] = location;\n\t\t}\n\t\tthis.attrs = attrs;\n\t}\n\tprivate createShader(type: number, source: string) {\n\t\tconst gl = this.gl;\n\t\tconst shader = gl.createShader(type);\n\t\tif (!shader) throw new Error(\"Failed to create shader\");\n\t\tgl.shaderSource(shader, source);\n\t\tgl.compileShader(shader);\n\t\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to compile shader for type ${type} \"${\n\t\t\t\t\tthis.label\n\t\t\t\t}\": ${gl.getShaderInfoLog(shader)}`,\n\t\t\t);\n\t\t}\n\t\treturn shader;\n\t}\n\tprivate createProgram() {\n\t\tconst gl = this.gl;\n\t\tconst program = gl.createProgram();\n\t\tif (!program) throw new Error(\"Failed to create program\");\n\t\tgl.attachShader(program, this.vertexShader);\n\t\tgl.attachShader(program, this.fragmentShader);\n\t\tgl.linkProgram(program);\n\t\tgl.validateProgram(program);\n\t\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\t\tconst errLog = gl.getProgramInfoLog(program);\n\t\t\tgl.deleteProgram(program);\n\t\t\tthrow new Error(`Failed to link program \"${this.label}\": ${errLog}`);\n\t\t}\n\t\treturn program;\n\t}\n\tuse() {\n\t\tconst gl = this.gl;\n\t\tgl.useProgram(this.program);\n\t}\n\tprivate notFoundUniforms: Set<string> = new Set();\n\tprivate warnUniformNotFound(name: string) {\n\t\tif (this.notFoundUniforms.has(name)) return;\n\t\tthis.notFoundUniforms.add(name);\n\t\tconsole.warn(\n\t\t\t`Failed to get uniform location for program \"${this.label}\": ${name}`,\n\t\t);\n\t}\n\tsetUniform1f(name: string, value: number) {\n\t\tconst gl = this.gl;\n\t\tconst location = gl.getUniformLocation(this.program, name);\n\t\tif (!location) this.warnUniformNotFound(name);\n\t\telse gl.uniform1f(location, value);\n\t}\n\tsetUniform2f(name: string, value1: number, value2: number) {\n\t\tconst gl = this.gl;\n\t\tconst location = gl.getUniformLocation(this.program, name);\n\t\tif (!location) this.warnUniformNotFound(name);\n\t\telse gl.uniform2f(location, value1, value2);\n\t}\n\tsetUniform1i(name: string, value: number) {\n\t\tconst gl = this.gl;\n\t\tconst location = gl.getUniformLocation(this.program, name);\n\t\tif (!location) this.warnUniformNotFound(name);\n\t\telse gl.uniform1i(location, value);\n\t}\n\tdispose() {\n\t\tconst gl = this.gl;\n\t\tgl.deleteShader(this.vertexShader);\n\t\tgl.deleteShader(this.fragmentShader);\n\t\tgl.deleteProgram(this.program);\n\t}\n}\n\nclass Mesh implements Disposable {\n\tprotected vertexWidth = 0;\n\tprotected vertexHeight = 0;\n\tprivate vertexBuffer: WebGLBuffer;\n\tprivate indexBuffer: WebGLBuffer;\n\tprivate vertexData: Float32Array;\n\tprivate indexData: Uint16Array;\n\tprivate vertexIndexLength = 0;\n\t// 调试用途,开启线框模式\n\tprivate wireFrame = false;\n\tconstructor(\n\t\tprivate readonly gl: RenderingContext,\n\t\tprivate readonly attrPos: number | undefined,\n\t\tprivate readonly attrColor: number | undefined,\n\t\tprivate readonly attrUV: number | undefined,\n\t) {\n\t\tconst vertexBuf = gl.createBuffer();\n\t\tif (!vertexBuf) throw new Error(\"Failed to create vertex buffer\");\n\t\tthis.vertexBuffer = vertexBuf;\n\t\tconst indexBuf = gl.createBuffer();\n\t\tif (!indexBuf) throw new Error(\"Failed to create index buffer\");\n\t\tthis.indexBuffer = indexBuf;\n\n\t\tthis.bind();\n\n\t\tthis.vertexData = new Float32Array(0);\n\t\tthis.indexData = new Uint16Array(0);\n\n\t\tthis.resize(2, 2);\n\t\tthis.update();\n\t}\n\n\tsetWireFrame(enable: boolean) {\n\t\tthis.wireFrame = enable;\n\t\tthis.resize(this.vertexWidth, this.vertexHeight);\n\t}\n\n\tsetVertexPos(vx: number, vy: number, x: number, y: number): void {\n\t\tconst idx = (vx + vy * this.vertexWidth) * 7;\n\t\tif (idx >= this.vertexData.length - 1) {\n\t\t\tconsole.warn(\"Vertex position out of range\", idx, this.vertexData.length);\n\t\t\treturn;\n\t\t}\n\t\tthis.vertexData[idx] = x;\n\t\tthis.vertexData[idx + 1] = y;\n\t}\n\n\tsetVertexColor(\n\t\tvx: number,\n\t\tvy: number,\n\t\tr: number,\n\t\tg: number,\n\t\tb: number,\n\t): void {\n\t\tconst idx = (vx + vy * this.vertexWidth) * 7 + 2;\n\t\tif (idx >= this.vertexData.length - 2) {\n\t\t\tconsole.warn(\"Vertex color out of range\", idx, this.vertexData.length);\n\t\t\treturn;\n\t\t}\n\t\tthis.vertexData[idx] = r;\n\t\tthis.vertexData[idx + 1] = g;\n\t\tthis.vertexData[idx + 2] = b;\n\t}\n\n\tsetVertexUV(vx: number, vy: number, x: number, y: number): void {\n\t\tconst idx = (vx + vy * this.vertexWidth) * 7 + 5;\n\t\tif (idx >= this.vertexData.length - 1) {\n\t\t\tconsole.warn(\"Vertex UV out of range\", idx, this.vertexData.length);\n\t\t\treturn;\n\t\t}\n\t\tthis.vertexData[idx] = x;\n\t\tthis.vertexData[idx + 1] = y;\n\t}\n\n\t// 批量设置顶点数据的优化方法\n\tsetVertexData(\n\t\tvx: number,\n\t\tvy: number,\n\t\tx: number,\n\t\ty: number,\n\t\tr: number,\n\t\tg: number,\n\t\tb: number,\n\t\tu: number,\n\t\tv: number,\n\t): void {\n\t\tconst idx = (vx + vy * this.vertexWidth) * 7;\n\t\tif (idx >= this.vertexData.length - 6) {\n\t\t\tconsole.warn(\"Vertex data out of range\", idx, this.vertexData.length);\n\t\t\treturn;\n\t\t}\n\t\tconst data = this.vertexData;\n\t\tdata[idx] = x;\n\t\tdata[idx + 1] = y;\n\t\tdata[idx + 2] = r;\n\t\tdata[idx + 3] = g;\n\t\tdata[idx + 4] = b;\n\t\tdata[idx + 5] = u;\n\t\tdata[idx + 6] = v;\n\t}\n\n\tgetVertexIndexLength(): number {\n\t\treturn this.vertexIndexLength;\n\t}\n\n\tdraw() {\n\t\tconst gl = this.gl;\n\n\t\tif (this.wireFrame) {\n\t\t\tgl.drawElements(gl.LINES, this.vertexIndexLength, gl.UNSIGNED_SHORT, 0);\n\t\t} else {\n\t\t\tgl.drawElements(\n\t\t\t\tgl.TRIANGLES,\n\t\t\t\tthis.vertexIndexLength,\n\t\t\t\tgl.UNSIGNED_SHORT,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\t}\n\n\tresize(vertexWidth: number, vertexHeight: number): void {\n\t\tthis.vertexWidth = vertexWidth;\n\t\tthis.vertexHeight = vertexHeight;\n\t\t// 2 个顶点坐标 + 3 个颜色值 + 2 个 UV 坐标\n\t\tthis.vertexIndexLength = vertexWidth * vertexHeight * 6;\n\t\tif (this.wireFrame) {\n\t\t\tthis.vertexIndexLength = vertexWidth * vertexHeight * 10;\n\t\t}\n\t\tconst vertexData = new Float32Array(\n\t\t\tvertexWidth * vertexHeight * (2 + 3 + 2),\n\t\t);\n\t\tconst indexData = new Uint16Array(this.vertexIndexLength);\n\t\tthis.vertexData = vertexData;\n\t\tthis.indexData = indexData;\n\t\tfor (let y = 0; y < vertexHeight; y++) {\n\t\t\tfor (let x = 0; x < vertexWidth; x++) {\n\t\t\t\tconst px = (x / (vertexWidth - 1)) * 2 - 1;\n\t\t\t\tconst py = (y / (vertexHeight - 1)) * 2 - 1;\n\t\t\t\tthis.setVertexPos(x, y, px || 0, py || 0);\n\t\t\t\tthis.setVertexColor(x, y, 1, 1, 1);\n\t\t\t\tthis.setVertexUV(x, y, x / (vertexWidth - 1), y / (vertexHeight - 1));\n\t\t\t}\n\t\t}\n\t\tfor (let y = 0; y < vertexHeight - 1; y++) {\n\t\t\tfor (let x = 0; x < vertexWidth - 1; x++) {\n\t\t\t\tif (this.wireFrame) {\n\t\t\t\t\tconst idx = (y * vertexWidth + x) * 10;\n\n\t\t\t\t\tindexData[idx] = y * vertexWidth + x;\n\t\t\t\t\tindexData[idx + 1] = y * vertexWidth + x + 1;\n\n\t\t\t\t\tindexData[idx + 2] = y * vertexWidth + x + 1;\n\t\t\t\t\tindexData[idx + 3] = (y + 1) * vertexWidth + x;\n\n\t\t\t\t\tindexData[idx + 4] = (y + 1) * vertexWidth + x;\n\t\t\t\t\tindexData[idx + 5] = (y + 1) * vertexWidth + x + 1;\n\n\t\t\t\t\tindexData[idx + 6] = (y + 1) * vertexWidth + x + 1;\n\t\t\t\t\tindexData[idx + 7] = y * vertexWidth + x + 1;\n\n\t\t\t\t\tindexData[idx + 8] = y * vertexWidth + x;\n\t\t\t\t\tindexData[idx + 9] = (y + 1) * vertexWidth + x;\n\t\t\t\t} else {\n\t\t\t\t\tconst idx = (y * vertexWidth + x) * 6;\n\t\t\t\t\tindexData[idx] = y * vertexWidth + x;\n\t\t\t\t\tindexData[idx + 1] = y * vertexWidth + x + 1;\n\t\t\t\t\tindexData[idx + 2] = (y + 1) * vertexWidth + x;\n\t\t\t\t\tindexData[idx + 3] = y * vertexWidth + x + 1;\n\t\t\t\t\tindexData[idx + 4] = (y + 1) * vertexWidth + x + 1;\n\t\t\t\t\tindexData[idx + 5] = (y + 1) * vertexWidth + x;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst gl = this.gl;\n\t\tgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n\t\tgl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indexData, gl.STATIC_DRAW);\n\t}\n\n\tbind() {\n\t\tconst gl = this.gl;\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n\t\tgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n\n\t\tif (this.attrPos !== undefined) {\n\t\t\tgl.vertexAttribPointer(this.attrPos, 2, gl.FLOAT, false, 4 * 7, 0);\n\t\t\tgl.enableVertexAttribArray(this.attrPos);\n\t\t}\n\t\tif (this.attrColor !== undefined) {\n\t\t\tgl.vertexAttribPointer(this.attrColor, 3, gl.FLOAT, false, 4 * 7, 4 * 2);\n\t\t\tgl.enableVertexAttribArray(this.attrColor);\n\t\t}\n\t\tif (this.attrUV !== undefined) {\n\t\t\tgl.vertexAttribPointer(this.attrUV, 2, gl.FLOAT, false, 4 * 7, 4 * 5);\n\t\t\tgl.enableVertexAttribArray(this.attrUV);\n\t\t}\n\t}\n\n\tupdate() {\n\t\tconst gl = this.gl;\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n\t\tgl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.DYNAMIC_DRAW);\n\t}\n\n\tdispose(): void {\n\t\tthis.gl.deleteBuffer(this.vertexBuffer);\n\t\tthis.gl.deleteBuffer(this.indexBuffer);\n\t}\n}\n\nclass ControlPoint {\n\tcolor: Vec3 = Vec3.fromValues(1, 1, 1);\n\tlocation: Vec2 = Vec2.fromValues(0, 0);\n\tuTangent: Vec2 = Vec2.fromValues(0, 0);\n\tvTangent: Vec2 = Vec2.fromValues(0, 0);\n\tprivate _uRot = 0;\n\tprivate _vRot = 0;\n\tprivate _uScale = 1;\n\tprivate _vScale = 1;\n\n\tconstructor() {\n\t\tObject.seal(this);\n\t}\n\n\tget uRot() {\n\t\treturn this._uRot;\n\t}\n\n\tget vRot() {\n\t\treturn this._vRot;\n\t}\n\n\tset uRot(value: number) {\n\t\tthis._uRot = value;\n\t\tthis.updateUTangent();\n\t}\n\n\tset vRot(value: number) {\n\t\tthis._vRot = value;\n\t\tthis.updateVTangent();\n\t}\n\n\tget uScale() {\n\t\treturn this._uScale;\n\t}\n\n\tget vScale() {\n\t\treturn this._vScale;\n\t}\n\n\tset uScale(value: number) {\n\t\tthis._uScale = value;\n\t\tthis.updateUTangent();\n\t}\n\n\tset vScale(value: number) {\n\t\tthis._vScale = value;\n\t\tthis.updateVTangent();\n\t}\n\n\tprivate updateUTangent() {\n\t\tthis.uTangent[0] = Math.cos(this._uRot) * this._uScale;\n\t\tthis.uTangent[1] = Math.sin(this._uRot) * this._uScale;\n\t}\n\n\tprivate updateVTangent() {\n\t\tthis.vTangent[0] = -Math.sin(this._vRot) * this._vScale;\n\t\tthis.vTangent[1] = Math.cos(this._vRot) * this._vScale;\n\t}\n}\n\nconst H = Mat4.fromValues(2, -2, 1, 1, -3, 3, -2, -1, 0, 0, 1, 0, 1, 0, 0, 0);\nconst H_T = Mat4.clone(H).transpose();\n\nfunction meshCoefficients(\n\tp00: ControlPoint,\n\tp01: ControlPoint,\n\tp10: ControlPoint,\n\tp11: ControlPoint,\n\taxis: \"x\" | \"y\",\n\toutput = Mat4.create(),\n): Mat4 {\n\tconst l = (p: ControlPoint) => p.location[axis];\n\tconst u = (p: ControlPoint) => p.uTangent[axis];\n\tconst v = (p: ControlPoint) => p.vTangent[axis];\n\n\toutput[0] = l(p00);\n\toutput[1] = l(p01);\n\toutput[2] = v(p00);\n\toutput[3] = v(p01);\n\toutput[4] = l(p10);\n\toutput[5] = l(p11);\n\toutput[6] = v(p10);\n\toutput[7] = v(p11);\n\toutput[8] = u(p00);\n\toutput[9] = u(p01);\n\toutput[10] = 0;\n\toutput[11] = 0;\n\toutput[12] = u(p10);\n\toutput[13] = u(p11);\n\toutput[14] = 0;\n\toutput[15] = 0;\n\n\treturn output;\n}\n\nfunction colorCoefficients(\n\tp00: ControlPoint,\n\tp01: ControlPoint,\n\tp10: ControlPoint,\n\tp11: ControlPoint,\n\taxis: \"r\" | \"g\" | \"b\",\n\toutput = Mat4.create(),\n): Mat4 {\n\tconst c = (p: ControlPoint) => p.color[axis];\n\toutput.fill(0);\n\toutput[0] = c(p00);\n\toutput[1] = c(p01);\n\toutput[4] = c(p10);\n\toutput[5] = c(p11);\n\t// return Mat4.fromValues(\n\t// c(p00), c(p01), 0, 0,\n\t// c(p10), c(p11), 0, 0,\n\t// 0, 0, 0, 0,\n\t// 0, 0, 0, 0,\n\t// );\n\treturn output;\n}\n\nclass Map2D<T> {\n\tprivate _width = 0;\n\tprivate _height = 0;\n\tprivate _data: T[] = [];\n\tconstructor(width: number, height: number) {\n\t\tthis.resize(width, height);\n\t\tObject.seal(this);\n\t}\n\tresize(width: number, height: number) {\n\t\tthis._width = width;\n\t\tthis._height = height;\n\t\tthis._data = new Array(width * height).fill(0);\n\t}\n\tset(x: number, y: number, value: T) {\n\t\tthis._data[x + y * this._width] = value;\n\t}\n\tget(x: number, y: number) {\n\t\treturn this._data[x + y * this._width];\n\t}\n\tget width() {\n\t\treturn this._width;\n\t}\n\tget height() {\n\t\treturn this._height;\n\t}\n}\n\n// Bicubic Hermite Patch Mesh\nclass BHPMesh extends Mesh {\n\t/**\n\t * 细分级别,越大曲线越平滑,但是性能消耗也越大\n\t */\n\tprivate _subDivisions = 10;\n\tprivate _controlPoints: Map2D<ControlPoint> = new Map2D(3, 3);\n\n\tconstructor(\n\t\tgl: RenderingContext,\n\t\tattrPos: number,\n\t\tattrColor: number,\n\t\tattrUV: number,\n\t) {\n\t\tsuper(gl, attrPos, attrColor, attrUV);\n\t\tthis.resizeControlPoints(3, 3);\n\t\tObject.seal(this);\n\t}\n\toverride setWireFrame(enable: boolean) {\n\t\tsuper.setWireFrame(enable);\n\t\tthis.updateMesh();\n\t}\n\t/**\n\t * 以当前的控制点矩阵大小和细分级别为参考重新设置细分级别,此操作不会重设控制点数据\n\t * @param subDivisions 细分级别\n\t */\n\tresetSubdivition(subDivisions: number) {\n\t\tthis._subDivisions = subDivisions;\n\t\tsuper.resize(\n\t\t\t(this._controlPoints.width - 1) * subDivisions,\n\t\t\t(this._controlPoints.height - 1) * subDivisions,\n\t\t);\n\t}\n\t/**\n\t * 重设控制点矩阵尺寸,将会重置所有控制点的颜色和坐标数据\n\t * 请在调用此方法后重新设置颜色和坐标,并调用 updateMesh 方法更新网格\n\t * @param width 控制点宽度数量,必须大于等于 2\n\t * @param height 控制点高度数量,必须大于等于 2\n\t */\n\tresizeControlPoints(width: number, height: number) {\n\t\tif (!(width >= 2 && height >= 2)) {\n\t\t\tthrow new Error(\"Control points must be larger than 3x3 or equal\");\n\t\t}\n\t\tthis._controlPoints.resize(width, height);\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst point = new ControlPoint();\n\t\t\t\tpoint.location.x = (x / (width - 1)) * 2 - 1;\n\t\t\t\tpoint.location.y = (y / (height - 1)) * 2 - 1;\n\t\t\t\tpoint.uTangent.x = 2 / (width - 1);\n\t\t\t\tpoint.vTangent.y = 2 / (height - 1);\n\t\t\t\tthis._controlPoints.set(x, y, point);\n\t\t\t}\n\t\t}\n\t\tthis.resetSubdivition(this._subDivisions);\n\t}\n\t/**\n\t * 获取指定位置的控制点,然后可以设置颜色和坐标属性\n\t * 留意颜色属性和坐标属性的值范围均参考 WebGL 的定义\n\t * 即颜色各个组件取值 [0-1],坐标取值 [-1, 1]\n\t * 点的位置以画面左下角为原点 (0,0)\n\t * @param x 需要获取的控制点的 x 坐标\n\t * @param y 需要获取的控制点的 y 坐标\n\t * @returns 控制点对象\n\t */\n\tgetControlPoint(x: number, y: number) {\n\t\treturn this._controlPoints.get(x, y);\n\t}\n\t// 预分配重复使用的矩阵,避免频繁创建\n\tprivate tempX = Mat4.create();\n\tprivate tempY = Mat4.create();\n\tprivate tempR = Mat4.create();\n\tprivate tempG = Mat4.create();\n\tprivate tempB = Mat4.create();\n\n\tprivate tempXAcc = Mat4.create();\n\tprivate tempYAcc = Mat4.create();\n\tprivate tempRAcc = Mat4.create();\n\tprivate tempGAcc = Mat4.create();\n\tprivate tempBAcc = Mat4.create();\n\n\tprivate tempUx = Vec4.create();\n\tprivate tempUy = Vec4.create();\n\tprivate tempUr = Vec4.create();\n\tprivate tempUg = Vec4.create();\n\tprivate tempUb = Vec4.create();\n\n\tprivate precomputeMatrix(M: Mat4, output: Mat4) {\n\t\toutput.copy(M).transpose();\n\t\tMat4.mul(output, output, H);\n\t\tMat4.mul(output, H_T, output);\n\t\treturn output;\n\t}\n\n\t/**\n\t * 更新最终呈现的网格数据,此方法应在所有控制点或细分参数的操作完成后调用\n\t */\n\tupdateMesh() {\n\t\tconst subDivM1 = this._subDivisions - 1;\n\t\tconst tW = subDivM1 * (this._controlPoints.height - 1);\n\t\tconst tH = subDivM1 * (this._controlPoints.width - 1);\n\t\tconst controlPointsWidth = this._controlPoints.width;\n\t\tconst controlPointsHeight = this._controlPoints.height;\n\t\tconst subDivisions = this._subDivisions;\n\n\t\t// 预计算常用值\n\t\tconst invSubDivM1 = 1 / subDivM1;\n\t\tconst invTH = 1 / tH;\n\t\tconst invTW = 1 / tW;\n\n\t\t// 预计算 u 和 v 的幂次\n\t\tconst normPowers = new Float32Array(subDivisions * 4);\n\t\tfor (let i = 0; i < subDivisions; i++) {\n\t\t\tconst norm = i * invSubDivM1;\n\t\t\tconst idx = i * 4;\n\t\t\tnormPowers[idx] = norm ** 3;\n\t\t\tnormPowers[idx + 1] = norm ** 2;\n\t\t\tnormPowers[idx + 2] = norm;\n\t\t\tnormPowers[idx + 3] = 1;\n\t\t}\n\n\t\tfor (let x = 0; x < controlPointsWidth - 1; x++) {\n\t\t\tfor (let y = 0; y < controlPointsHeight - 1; y++) {\n\t\t\t\tconst p00 = this._controlPoints.get(x, y);\n\t\t\t\tconst p01 = this._controlPoints.get(x, y + 1);\n\t\t\t\tconst p10 = this._controlPoints.get(x + 1, y);\n\t\t\t\tconst p11 = this._controlPoints.get(x + 1, y + 1);\n\n\t\t\t\t// 复用预分配的矩阵\n\t\t\t\tmeshCoefficients(p00, p01, p10, p11, \"x\", this.tempX);\n\t\t\t\tmeshCoefficients(p00, p01, p10, p11, \"y\", this.tempY);\n\t\t\t\tcolorCoefficients(p00, p01, p10, p11, \"r\", this.tempR);\n\t\t\t\tcolorCoefficients(p00, p01, p10, p11, \"g\", this.tempG);\n\t\t\t\tcolorCoefficients(p00, p01, p10, p11, \"b\", this.tempB);\n\n\t\t\t\t// 预计算累加矩阵\n\t\t\t\tthis.precomputeMatrix(this.tempX, this.tempXAcc);\n\t\t\t\tthis.precomputeMatrix(this.tempY, this.tempYAcc);\n\t\t\t\tthis.precomputeMatrix(this.tempR, this.tempRAcc);\n\t\t\t\tthis.precomputeMatrix(this.tempG, this.tempGAcc);\n\t\t\t\tthis.precomputeMatrix(this.tempB, this.tempBAcc);\n\n\t\t\t\tconst sX = x / (controlPointsWidth - 1);\n\t\t\t\tconst sY = y / (controlPointsHeight - 1);\n\t\t\t\tconst baseVx = y * subDivisions;\n\t\t\t\tconst baseVy = x * subDivisions;\n\n\t\t\t\tfor (let u = 0; u < subDivisions; u++) {\n\t\t\t\t\tconst vxOffset = baseVx + u;\n\t\t\t\t\tconst uIdx = u * 4;\n\n\t\t\t\t\tthis.tempUx[0] = normPowers[uIdx];\n\t\t\t\t\tthis.tempUx[1] = normPowers[uIdx + 1];\n\t\t\t\t\tthis.tempUx[2] = normPowers[uIdx + 2];\n\t\t\t\t\tthis.tempUx[3] = normPowers[uIdx + 3];\n\t\t\t\t\tVec4.transformMat4(this.tempUx, this.tempUx, this.tempXAcc);\n\n\t\t\t\t\tthis.tempUy[0] = normPowers[uIdx];\n\t\t\t\t\tthis.tempUy[1] = normPowers[uIdx + 1];\n\t\t\t\t\tthis.tempUy[2] = normPowers[uIdx + 2];\n\t\t\t\t\tthis.tempUy[3] = normPowers[uIdx + 3];\n\t\t\t\t\tVec4.transformMat4(this.tempUy, this.tempUy, this.tempYAcc);\n\n\t\t\t\t\tthis.tempUr[0] = normPowers[uIdx];\n\t\t\t\t\tthis.tempUr[1] = normPowers[uIdx + 1];\n\t\t\t\t\tthis.tempUr[2] = normPowers[uIdx + 2];\n\t\t\t\t\tthis.tempUr[3] = normPowers[uIdx + 3];\n\t\t\t\t\tVec4.transformMat4(this.tempUr, this.tempUr, this.tempRAcc);\n\n\t\t\t\t\tthis.tempUg[0] = normPowers[uIdx];\n\t\t\t\t\tthis.tempUg[1] = normPowers[uIdx + 1];\n\t\t\t\t\tthis.tempUg[2] = normPowers[uIdx + 2];\n\t\t\t\t\tthis.tempUg[3] = normPowers[uIdx + 3];\n\t\t\t\t\tVec4.transformMat4(this.tempUg, this.tempUg, this.tempGAcc);\n\n\t\t\t\t\tthis.tempUb[0] = normPowers[uIdx];\n\t\t\t\t\tthis.tempUb[1] = normPowers[uIdx + 1];\n\t\t\t\t\tthis.tempUb[2] = normPowers[uIdx + 2];\n\t\t\t\t\tthis.tempUb[3] = normPowers[uIdx + 3];\n\t\t\t\t\tVec4.transformMat4(this.tempUb, this.tempUb, this.tempBAcc);\n\n\t\t\t\t\tfor (let v = 0; v < subDivisions; v++) {\n\t\t\t\t\t\tconst vy = baseVy + v;\n\t\t\t\t\t\tconst vIdx = v * 4;\n\n\t\t\t\t\t\tconst v0 = normPowers[vIdx];\n\t\t\t\t\t\tconst v1 = normPowers[vIdx + 1];\n\t\t\t\t\t\tconst v2 = normPowers[vIdx + 2];\n\t\t\t\t\t\tconst v3 = normPowers[vIdx + 3];\n\n\t\t\t\t\t\tconst px =\n\t\t\t\t\t\t\tv0 * this.tempUx[0] +\n\t\t\t\t\t\t\tv1 * this.tempUx[1] +\n\t\t\t\t\t\t\tv2 * this.tempUx[2] +\n\t\t\t\t\t\t\tv3 * this.tempUx[3];\n\t\t\t\t\t\tconst py =\n\t\t\t\t\t\t\tv0 * this.tempUy[0] +\n\t\t\t\t\t\t\tv1 * this.tempUy[1] +\n\t\t\t\t\t\t\tv2 * this.tempUy[2] +\n\t\t\t\t\t\t\tv3 * this.tempUy[3];\n\t\t\t\t\t\tconst pr =\n\t\t\t\t\t\t\tv0 * this.tempUr[0] +\n\t\t\t\t\t\t\tv1 * this.tempUr[1] +\n\t\t\t\t\t\t\tv2 * this.tempUr[2] +\n\t\t\t\t\t\t\tv3 * this.tempUr[3];\n\t\t\t\t\t\tconst pg =\n\t\t\t\t\t\t\tv0 * this.tempUg[0] +\n\t\t\t\t\t\t\tv1 * this.tempUg[1] +\n\t\t\t\t\t\t\tv2 * this.tempUg[2] +\n\t\t\t\t\t\t\tv3 * this.tempUg[3];\n\t\t\t\t\t\tconst pb =\n\t\t\t\t\t\t\tv0 * this.tempUb[0] +\n\t\t\t\t\t\t\tv1 * this.tempUb[1] +\n\t\t\t\t\t\t\tv2 * this.tempUb[2] +\n\t\t\t\t\t\t\tv3 * this.tempUb[3];\n\n\t\t\t\t\t\tconst uvX = sX + v * invTH;\n\t\t\t\t\t\tconst uvY = 1 - sY - u * invTW;\n\n\t\t\t\t\t\t// 使用批量设置方法减少数组访问次数\n\t\t\t\t\t\tthis.setVertexData(vxOffset, vy, px, py, pr, pg, pb, uvX, uvY);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.update();\n\t}\n}\n\nclass GLTexture implements Disposable {\n\treadonly tex: WebGLTexture;\n\n\tconstructor(\n\t\tprivate gl: WebGLRenderingContext,\n\t\talbumImageData: ImageData,\n\t) {\n\t\tconst albumTexture = gl.createTexture();\n\t\tif (!albumTexture) throw new Error(\"Failed to create texture\");\n\t\tthis.tex = albumTexture;\n\t\tgl.activeTexture(gl.TEXTURE0);\n\t\tgl.bindTexture(gl.TEXTURE_2D, albumTexture);\n\t\tgl.texImage2D(\n\t\t\tgl.TEXTURE_2D,\n\t\t\t0,\n\t\t\tgl.RGBA,\n\t\t\tgl.RGBA,\n\t\t\tgl.UNSIGNED_BYTE,\n\t\t\talbumImageData,\n\t\t);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);\n\t}\n\n\tbind() {\n\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, this.tex);\n\t}\n\n\tdispose(): void {\n\t\tthis.gl.deleteTexture(this.tex);\n\t}\n}\n\nfunction createOffscreenCanvas(width: number, height: number) {\n\tif (\"OffscreenCanvas\" in window) return new OffscreenCanvas(width, height);\n\tconst canvas = document.createElement(\"canvas\");\n\tcanvas.width = width;\n\tcanvas.height = height;\n\treturn canvas;\n}\n\ninterface MeshState {\n\tmesh: BHPMesh;\n\ttexture: GLTexture;\n\talpha: number;\n}\n\nexport class MeshGradientRenderer extends BaseRenderer {\n\tprivate gl: RenderingContext;\n\tprivate lastFrameTime = 0;\n\tprivate frameTime = 0;\n\t// private currentImageData?: ImageData;\n\tprivate lastTickTime = 0;\n\tprivate smoothedVolume = 0;\n\tprivate volume = 0;\n\tprivate tickHandle = 0;\n\tprivate maxFPS = 60;\n\tprivate paused = false;\n\tprivate staticMode = false;\n\tprivate mainProgram: GLProgram;\n\tprivate quadProgram: GLProgram;\n\tprivate quadBuffer: WebGLBuffer;\n\tprivate fbo: WebGLFramebuffer | null = null;\n\tprivate fboTexture: WebGLTexture | null = null;\n\tprivate manualControl = false;\n\tprivate reduceImageSizeCanvas = createOffscreenCanvas(\n\t\t32,\n\t\t32,\n\t) as HTMLCanvasElement;\n\tprivate targetSize = Vec2.fromValues(0, 0);\n\tprivate currentSize = Vec2.fromValues(0, 0);\n\tprivate isNoCover = true;\n\tprivate meshStates: MeshState[] = [];\n\tprivate _disposed = false;\n\t// 性能监控\n\tprivate frameCount = 0;\n\tprivate lastFPSUpdate = 0;\n\tprivate currentFPS = 0;\n\tprivate enablePerformanceMonitoring = false;\n\n\tsetManualControl(enable: boolean): void {\n\t\tthis.manualControl = enable;\n\t}\n\n\tsetWireFrame(enable: boolean): void {\n\t\tfor (const state of this.meshStates) {\n\t\t\tstate.mesh.setWireFrame(enable);\n\t\t}\n\t}\n\n\tgetControlPoint(x: number, y: number): ControlPoint | undefined {\n\t\treturn this.meshStates[this.meshStates.length - 1]?.mesh?.getControlPoint(\n\t\t\tx,\n\t\t\ty,\n\t\t);\n\t}\n\n\tresizeControlPoints(width: number, height: number): void {\n\t\tthis.meshStates[this.meshStates.length - 1]?.mesh?.resizeControlPoints(\n\t\t\twidth,\n\t\t\theight,\n\t\t);\n\t}\n\n\tresetSubdivition(subDivisions: number): void {\n\t\tthis.meshStates[this.meshStates.length - 1]?.mesh?.resetSubdivition(\n\t\t\tsubDivisions,\n\t\t);\n\t}\n\n\tprivate onTick(tickTime: number) {\n\t\tthis.tickHandle = 0;\n\t\tif (this.paused) return;\n\t\tif (this._disposed) return;\n\n\t\t// 更新性能统计\n\t\tthis.updatePerformanceStats(tickTime);\n\n\t\tconst interval = 1000 / this.maxFPS;\n\t\tconst delta = tickTime - this.lastTickTime;\n\t\tif (delta < interval) {\n\t\t\tthis.requestTick();\n\t\t\treturn;\n\t\t}\n\n\t\tif (Number.isNaN(this.lastFrameTime)) {\n\t\t\tthis.lastFrameTime = tickTime;\n\t\t}\n\t\tconst frameDelta = tickTime - this.lastFrameTime;\n\t\tthis.lastFrameTime = tickTime;\n\t\t// 减去多余的时间,避免帧率漂移(例如高刷显示器限制低帧率时)\n\t\tthis.lastTickTime = tickTime - (delta % interval);\n\n\t\tthis.frameTime += frameDelta * this.flowSpeed;\n\n\t\tif (!(this.onRedraw(this.frameTime, frameDelta) && this.staticMode)) {\n\t\t\tthis.requestTick();\n\t\t} else if (this.staticMode) {\n\t\t\tthis.lastFrameTime = Number.NaN;\n\t\t}\n\t}\n\n\tprivate checkIfResize() {\n\t\tconst [tW, tH] = [this.targetSize.x, this.targetSize.y];\n\t\tconst [cW, cH] = [this.currentSize.x, this.currentSize.y];\n\t\tif (tW !== cW || tH !== cH) {\n\t\t\tsuper.onResize(tW, tH);\n\t\t\tconst gl = this.gl;\n\t\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\t\t\tgl.viewport(0, 0, tW, tH);\n\t\t\tthis.currentSize.x = tW;\n\t\t\tthis.currentSize.y = tH;\n\t\t\tif (tW > 0 && tH > 0) {\n\t\t\t\tthis.updateFBO(tW, tH);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate updateFBO(width: number, height: number) {\n\t\tconst gl = this.gl;\n\t\tif (this.fbo) gl.deleteFramebuffer(this.fbo);\n\t\tif (this.fboTexture) gl.deleteTexture(this.fboTexture);\n\n\t\tthis.fboTexture = gl.createTexture();\n\t\tgl.bindTexture(gl.TEXTURE_2D, this.fboTexture);\n\t\tgl.texImage2D(\n\t\t\tgl.TEXTURE_2D,\n\t\t\t0,\n\t\t\tgl.RGBA,\n\t\t\twidth,\n\t\t\theight,\n\t\t\t0,\n\t\t\tgl.RGBA,\n\t\t\tgl.UNSIGNED_BYTE,\n\t\t\tnull,\n\t\t);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\n\t\tthis.fbo = gl.createFramebuffer();\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);\n\t\tgl.framebufferTexture2D(\n\t\t\tgl.FRAMEBUFFER,\n\t\t\tgl.COLOR_ATTACHMENT0,\n\t\t\tgl.TEXTURE_2D,\n\t\t\tthis.fboTexture,\n\t\t\t0,\n\t\t);\n\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\t}\n\n\tprivate onRedraw(tickTime: number, delta: number) {\n\t\tconst latestMeshState = this.meshStates[this.meshStates.length - 1];\n\t\tlet canBeStatic = false;\n\n\t\t// 预计算常用值\n\t\tconst deltaFactor = delta / 500;\n\n\t\tif (latestMeshState) {\n\t\t\tlatestMeshState.mesh.bind();\n\t\t\t// 考虑到我们并不逐帧更新网格控制点,因此也不需要重复调用 updateMesh\n\t\t\tif (this.manualControl) latestMeshState.mesh.updateMesh();\n\n\t\t\tif (this.isNoCover) {\n\t\t\t\t// 批量处理alpha更新,减少循环开销\n\t\t\t\tlet hasActiveStates = false;\n\t\t\t\tfor (let i = this.meshStates.length - 1; i >= 0; i--) {\n\t\t\t\t\tconst state = this.meshStates[i];\n\t\t\t\t\t// 增加一个小的容错范围,避免浮点误差导致的过早删除\n\t\t\t\t\tif (state.alpha <= -0.1) {\n\t\t\t\t\t\t// 立即释放资源\n\t\t\t\t\t\tstate.mesh.dispose();\n\t\t\t\t\t\tstate.texture.dispose();\n\t\t\t\t\t\tthis.meshStates.splice(i, 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.alpha = Math.max(-0.1, state.alpha - deltaFactor);\n\t\t\t\t\t\thasActiveStates = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcanBeStatic = !hasActiveStates;\n\t\t\t} else {\n\t\t\t\t// 同样增加容错范围,允许稍微超过1以确保完全过渡完成\n\t\t\t\tif (latestMeshState.alpha >= 1.1) {\n\t\t\t\t\t// 批量清理旧状态\n\t\t\t\t\tconst deleted = this.meshStates.splice(0, this.meshStates.length - 1);\n\t\t\t\t\tfor (const state of deleted) {\n\t\t\t\t\t\tstate.mesh.dispose();\n\t\t\t\t\t\tstate.texture.dispose();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlatestMeshState.alpha = Math.min(\n\t\t\t\t\t\t1.1,\n\t\t\t\t\t\tlatestMeshState.alpha + deltaFactor,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcanBeStatic =\n\t\t\t\t\tthis.meshStates.length === 1 && latestMeshState.alpha >= 1.1;\n\t\t\t}\n\t\t}\n\n\t\tconst gl = this.gl;\n\t\tthis.checkIfResize();\n\n\t\tif (!this.fbo) return canBeStatic;\n\n\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\t\tgl.clearColor(0, 0, 0, 0);\n\t\tgl.clear(gl.COLOR_BUFFER_BIT);\n\n\t\tconst lerpFactor = Math.min(1.0, delta / 100.0);\n\t\tthis.smoothedVolume += (this.volume - this.smoothedVolume) * lerpFactor;\n\n\t\t// 渲染所有网格状态\n\t\tfor (const state of this.meshStates) {\n\t\t\t// 1. 渲染到 FBO\n\t\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);\n\t\t\tgl.disable(gl.BLEND);\n\t\t\tgl.clearColor(0, 0, 0, 0);\n\t\t\tgl.clear(gl.COLOR_BUFFER_BIT);\n\n\t\t\tthis.mainProgram.use();\n\t\t\tgl.activeTexture(gl.TEXTURE0);\n\t\t\tthis.mainProgram.setUniform1f(\"u_time\", tickTime / 10000);\n\t\t\tthis.mainProgram.setUniform1f(\n\t\t\t\t\"u_aspect\",\n\t\t\t\tthis.manualControl ? 1 : this.canvas.width / this.canvas.height,\n\t\t\t);\n\t\t\tthis.mainProgram.setUniform1i(\"u_texture\", 0);\n\t\t\tthis.mainProgram.setUniform1f(\"u_volume\", this.volume);\n\t\t\tthis.mainProgram.setUniform1f(\"u_alpha\", 1.0);\n\n\t\t\tstate.texture.bind();\n\t\t\tstate.mesh.bind();\n\t\t\tstate.mesh.draw();\n\n\t\t\t// 2. 渲染 FBO 到屏幕\n\t\t\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\t\t\tgl.enable(gl.BLEND);\n\t\t\tgl.blendFuncSeparate(\n\t\t\t\tgl.SRC_ALPHA,\n\t\t\t\tgl.ONE_MINUS_SRC_ALPHA,\n\t\t\t\tgl.ONE,\n\t\t\t\tgl.ONE_MINUS_SRC_ALPHA,\n\t\t\t);\n\t\t\tthis.quadProgram.use();\n\t\t\tthis.quadProgram.setUniform1i(\"u_texture\", 0);\n\t\t\tthis.quadProgram.setUniform1f(\n\t\t\t\t\"u_alpha\",\n\t\t\t\teaseInOutSine(Math.min(1, Math.max(0, state.alpha))),\n\t\t\t);\n\n\t\t\tgl.activeTexture(gl.TEXTURE0);\n\t\t\tgl.bindTexture(gl.TEXTURE_2D, this.fboTexture);\n\n\t\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n\t\t\tconst a_pos = this.quadProgram.attrs.a_pos;\n\t\t\tgl.vertexAttribPointer(a_pos, 2, gl.FLOAT, false, 0, 0);\n\t\t\tgl.enableVertexAttribArray(a_pos);\n\n\t\t\tgl.drawArrays(gl.TRIANGLES, 0, 6);\n\t\t\tgl.disableVertexAttribArray(a_pos);\n\t\t}\n\n\t\tgl.flush();\n\n\t\treturn canBeStatic;\n\t}\n\n\tprivate onTickBinded = this.onTick.bind(this);\n\n\tprivate requestTick() {\n\t\tif (this._disposed) return;\n\t\tif (this.tickHandle === 0)\n\t\t\tthis.tickHandle = requestAnimationFrame(this.onTickBinded);\n\t}\n\n\t// private supportTextureFloat = true;\n\n\tconstructor(canvas: HTMLCanvasElement) {\n\t\tsuper(canvas);\n\n\t\tconst gl = canvas.getContext(\"webgl\", { antialias: true });\n\t\tif (!gl) throw new Error(\"WebGL not supported\");\n\t\tif (!gl.getExtension(\"EXT_color_buffer_float\"))\n\t\t\tconsole.warn(\"EXT_color_buffer_float not supported\");\n\t\tif (!gl.getExtension(\"EXT_float_blend\")) {\n\t\t\tconsole.warn(\"EXT_float_blend not supported\");\n\t\t\t// this.supportTextureFloat = false;\n\t\t}\n\t\tif (!gl.getExtension(\"OES_texture_float_linear\"))\n\t\t\tconsole.warn(\"OES_texture_float_linear not supported\");\n\t\tif (!gl.getExtension(\"OES_texture_float\")) {\n\t\t\t// this.supportTextureFloat = false;\n\t\t\tconsole.warn(\"OES_texture_float not supported\");\n\t\t}\n\n\t\tthis.gl = gl;\n\t\tgl.enable(gl.BLEND);\n\t\tgl.blendFuncSeparate(\n\t\t\tgl.SRC_ALPHA,\n\t\t\tgl.ONE_MINUS_SRC_ALPHA,\n\t\t\tgl.ONE,\n\t\t\tgl.ONE_MINUS_SRC_ALPHA,\n\t\t);\n\t\tgl.enable(gl.DEPTH_TEST);\n\t\tgl.depthFunc(gl.ALWAYS);\n\n\t\tthis.mainProgram = new GLProgram(\n\t\t\tgl,\n\t\t\tmeshVertShader,\n\t\t\tmeshFragShader,\n\t\t\t\"main-program-mg\",\n\t\t);\n\n\t\tthis.quadProgram = new GLProgram(\n\t\t\tgl,\n\t\t\tquadVertShader,\n\t\t\tquadFragShader,\n\t\t\t\"quad-program\",\n\t\t);\n\t\tconst quadBuffer = gl.createBuffer();\n\t\tif (!quadBuffer) throw new Error(\"Failed to create quad buffer\");\n\t\tthis.quadBuffer = quadBuffer;\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n\t\tgl.bufferData(\n\t\t\tgl.ARRAY_BUFFER,\n\t\t\tnew Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n\t\t\tgl.STATIC_DRAW,\n\t\t);\n\n\t\tthis.requestTick();\n\t}\n\n\tprotected override onResize(width: number, height: number): void {\n\t\tthis.targetSize.x = Math.ceil(width);\n\t\tthis.targetSize.y = Math.ceil(height);\n\t\tthis.requestTick();\n\t}\n\n\toverride setStaticMode(enable: boolean): void {\n\t\tthis.staticMode = enable;\n\t\tthis.lastFrameTime = performance.now();\n\t\tthis.requestTick();\n\t}\n\toverride setFPS(fps: number): void {\n\t\tthis.maxFPS = fps;\n\t}\n\toverride pause(): void {\n\t\tif (this.tickHandle) {\n\t\t\tcancelAnimationFrame(this.tickHandle);\n\t\t\tthis.tickHandle = 0;\n\t\t}\n\t\tthis.paused = true;\n\t}\n\toverride resume(): void {\n\t\tthis.paused = false;\n\t\tthis.requestTick();\n\t}\n\toverride async setAlbum(\n\t\talbumSource?: string | HTMLImageElement | HTMLVideoElement,\n\t\tisVideo?: boolean,\n\t): Promise<void> {\n\t\tif (\n\t\t\talbumSource === undefined ||\n\t\t\t(typeof albumSource === \"string\" && albumSource.trim().length === 0)\n\t\t) {\n\t\t\tthis.isNoCover = true;\n\t\t\treturn;\n\t\t}\n\t\tlet res: HTMLImageElement | HTMLVideoElement | null = null;\n\t\tlet blob: Blob | null = null;\n\t\tlet remainRetryTimes = 5;\n\t\twhile (!res && remainRetryTimes > 0) {\n\t\t\ttry {\n\t\t\t\tif (typeof albumSource === \"string\") {\n\t\t\t\t\tif (!isVideo && \"createImageBitmap\" in window) {\n\t\t\t\t\t\t// 如果支持 createImageBitmap 且是图片,直接 fetch blob\n\t\t\t\t\t\tconst response = await fetch(albumSource);\n\t\t\t\t\t\tblob = await response.blob();\n\t\t\t\t\t\t// 仍然需要一个 HTMLImageElement 来获取原始宽高(如果后续需要)\n\t\t\t\t\t\t// 但这里我们主要依赖 blob 来创建 bitmap\n\t\t\t\t\t\tres = await loadResourceFromUrl(URL.createObjectURL(blob), false);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tres = await loadResourceFromUrl(albumSource, isVideo);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tres = await loadResourceFromElement(albumSource);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`failed on loading album resource, retrying (${remainRetryTimes})`,\n\t\t\t\t\t{\n\t\t\t\t\t\talbumSource,\n\t\t\t\t\t\terror,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tremainRetryTimes--;\n\t\t\t}\n\t\t}\n\t\tif (!res) {\n\t\t\tconsole.error(\"Failed to load album resource\", albumSource);\n\t\t\tthis.isNoCover = true;\n\t\t\treturn;\n\t\t}\n\t\tthis.isNoCover = false;\n\t\t// resize image\n\t\tconst c = this.reduceImageSizeCanvas;\n\t\tconst ctx = c.getContext(\"2d\", {\n\t\t\twillReadFrequently: true,\n\t\t});\n\t\tif (!ctx) throw new Error(\"Failed to create canvas context\");\n\t\tctx.clearRect(0, 0, c.width, c.height);\n\t\t// Safari 不支持 filter\n\t\t// ctx.filter = baseFilter;\n\t\tconst imgw =\n\t\t\tres instanceof HTMLVideoElement ? res.videoWidth : res.naturalWidth;\n\t\tconst imgh =\n\t\t\tres instanceof HTMLVideoElement ? res.videoHeight : res.naturalHeight;\n\t\tif (imgw * imgh === 0) throw new Error(\"Invalid image size\");\n\n\t\tlet bitmap: ImageBitmap | null = null;\n\t\ttry {\n\t\t\tif (\"createImageBitmap\" in window) {\n\t\t\t\t// 避免在主线程进行同步解码,使用 fetch 获取 blob 后再创建 ImageBitmap\n\t\t\t\tif (blob) {\n\t\t\t\t\tbitmap = await createImageBitmap(blob, {\n\t\t\t\t\t\tresizeWidth: c.width,\n\t\t\t\t\t\tresizeHeight: c.height,\n\t\t\t\t\t\tresizeQuality: \"low\",\n\t\t\t\t\t});\n\t\t\t\t\tURL.revokeObjectURL(res.src); // 释放 object URL\n\t\t\t\t} else {\n\t\t\t\t\tbitmap = await createImageBitmap(res, {\n\t\t\t\t\t\tresizeWidth: c.width,\n\t\t\t\t\t\tresizeHeight: c.height,\n\t\t\t\t\t\tresizeQuality: \"low\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconsole.warn(\"createImageBitmap failed\", e);\n\t\t}\n\n\t\tif (bitmap) {\n\t\t\tctx.drawImage(bitmap, 0, 0);\n\t\t\tbitmap.close();\n\t\t} else {\n\t\t\tctx.drawImage(res, 0, 0, imgw, imgh, 0, 0, c.width, c.height);\n\t\t}\n\n\t\tconst imageData = ctx.getImageData(0, 0, c.width, c.height);\n\n\t\t// 合并对比度、饱和度、亮度的处理,减少循环次数\n\t\tconst pixels = imageData.data;\n\t\tfor (let i = 0; i < pixels.length; i += 4) {\n\t\t\tlet r = pixels[i];\n\t\t\tlet g = pixels[i + 1];\n\t\t\tlet b = pixels[i + 2];\n\n\t\t\t// contrast 0.4\n\t\t\tr = (r - 128) * 0.4 + 128;\n\t\t\tg = (g - 128) * 0.4 + 128;\n\t\t\tb = (b - 128) * 0.4 + 128;\n\n\t\t\t// saturate 3.0\n\t\t\tconst gray = r * 0.3 + g * 0.59 + b * 0.11;\n\t\t\tr = gray * -2.0 + r * 3.0;\n\t\t\tg = gray * -2.0 + g * 3.0;\n\t\t\tb = gray * -2.0 + b * 3.0;\n\n\t\t\t// contrast 1.7\n\t\t\tr = (r - 128) * 1.7 + 128;\n\t\t\tg = (g - 128) * 1.7 + 128;\n\t\t\tb = (b - 128) * 1.7 + 128;\n\n\t\t\t// brightness 0.75\n\t\t\tpixels[i] = r * 0.75;\n\t\t\tpixels[i + 1] = g * 0.75;\n\t\t\tpixels[i + 2] = b * 0.75;\n\t\t}\n\n\t\tblurImage(imageData, 2, 4);\n\n\t\tif (this.manualControl && this.meshStates.length > 0) {\n\t\t\tthis.meshStates[0].texture.dispose();\n\t\t\tthis.meshStates[0].texture = new GLTexture(this.gl, imageData);\n\t\t} else {\n\t\t\tconst newMesh = new BHPMesh(\n\t\t\t\tthis.gl,\n\t\t\t\tthis.mainProgram.attrs.a_pos,\n\t\t\t\tthis.mainProgram.attrs.a_color,\n\t\t\t\tthis.mainProgram.attrs.a_uv,\n\t\t\t);\n\t\t\tnewMesh.resetSubdivition(50);\n\n\t\t\tconst chosenPreset =\n\t\t\t\tMath.random() > 0.8\n\t\t\t\t\t? generateControlPoints(6, 6)\n\t\t\t\t\t: CONTROL_POINT_PRESETS[\n\t\t\t\t\t\t\tMath.floor(Math.random() * CONTROL_POINT_PRESETS.length)\n\t\t\t\t\t\t];\n\n\t\t\tnewMesh.resizeControlPoints(chosenPreset.width, chosenPreset.height);\n\t\t\tconst uPower = 2 / (chosenPreset.width - 1);\n\t\t\tconst vPower = 2 / (chosenPreset.height - 1);\n\t\t\tfor (const cp of chosenPreset.conf) {\n\t\t\t\tconst p = newMesh.getControlPoint(cp.cx, cp.cy);\n\t\t\t\tp.location.x = cp.x;\n\t\t\t\tp.location.y = cp.y;\n\t\t\t\tp.uRot = (cp.ur * Math.PI) / 180;\n\t\t\t\tp.vRot = (cp.vr * Math.PI) / 180;\n\t\t\t\tp.uScale = uPower * cp.up;\n\t\t\t\tp.vScale = vPower * cp.vp;\n\t\t\t}\n\n\t\t\tnewMesh.updateMesh();\n\t\t\t// this.currentImageData = imageData;\n\n\t\t\tconst albumTexture = new GLTexture(this.gl, imageData);\n\t\t\tconst newState: MeshState = {\n\t\t\t\tmesh: newMesh,\n\t\t\t\ttexture: albumTexture,\n\t\t\t\talpha: 0,\n\t\t\t};\n\t\t\tthis.meshStates.push(newState);\n\t\t}\n\n\t\tthis.requestTick();\n\t}\n\toverride setLowFreqVolume(volume: number): void {\n\t\tthis.volume = volume / 10;\n\t}\n\toverride setHasLyric(_hasLyric: boolean): void {\n\t\t// 不再考虑实现\n\t}\n\n\toverride dispose(): void {\n\t\tsuper.dispose();\n\t\tif (this.tickHandle) {\n\t\t\tcancelAnimationFrame(this.tickHandle);\n\t\t\tthis.tickHandle = 0;\n\t\t}\n\t\tthis._disposed = true;\n\t\tthis.mainProgram.dispose();\n\t\tthis.quadProgram.dispose();\n\t\tthis.gl.deleteBuffer(this.quadBuffer);\n\t\tif (this.fbo) this.gl.deleteFramebuffer(this.fbo);\n\t\tif (this.fboTexture) this.gl.deleteTexture(this.fboTexture);\n\t\tfor (const state of this.meshStates) {\n\t\t\tstate.mesh.dispose();\n\t\t\tstate.texture.dispose();\n\t\t}\n\t}\n\n\tenablePerformanceMonitor(enable: boolean): void {\n\t\tthis.enablePerformanceMonitoring = enable;\n\t\tif (enable) {\n\t\t\tthis.frameCount = 0;\n\t\t\tthis.lastFPSUpdate = performance.now();\n\t\t}\n\t}\n\n\tgetCurrentFPS(): number {\n\t\treturn this.currentFPS;\n\t}\n\n\tprivate updatePerformanceStats(tickTime: number) {\n\t\tif (!this.enablePerformanceMonitoring) return;\n\n\t\tthis.frameCount++;\n\t\tif (tickTime - this.lastFPSUpdate > 1000) {\n\t\t\tthis.currentFPS = this.frameCount;\n\t\t\tthis.frameCount = 0;\n\t\t\tthis.lastFPSUpdate = tickTime;\n\t\t}\n\t}\n}\n","import { Application } from \"@pixi/app\";\nimport { Texture } from \"@pixi/core\";\nimport { Container } from \"@pixi/display\";\nimport { BlurFilter } from \"@pixi/filter-blur\";\nimport { BulgePinchFilter } from \"@pixi/filter-bulge-pinch\";\nimport { ColorMatrixFilter } from \"@pixi/filter-color-matrix\";\nimport { Sprite } from \"@pixi/sprite\";\nimport {\n\tloadResourceFromElement,\n\tloadResourceFromUrl,\n} from \"../utils/resource\";\nimport { BaseRenderer } from \"./base\";\n\nclass TimedContainer extends Container {\n\tpublic time = 0;\n}\n\nexport class PixiRenderer extends BaseRenderer {\n\tprivate app: Application;\n\tprivate curContainer?: TimedContainer;\n\tprivate staticMode = false;\n\tprivate lastContainer: Set<TimedContainer> = new Set();\n\tprivate onTick = (delta: number): void => {\n\t\tfor (const lastContainer of this.lastContainer) {\n\t\t\tlastContainer.alpha = Math.max(0, lastContainer.alpha - delta / 60);\n\t\t\tif (lastContainer.alpha <= 0) {\n\t\t\t\tthis.app.stage.removeChild(lastContainer);\n\t\t\t\tthis.lastContainer.delete(lastContainer);\n\t\t\t\tlastContainer.destroy(true);\n\t\t\t}\n\t\t}\n\n\t\tif (this.curContainer) {\n\t\t\tthis.curContainer.alpha = Math.min(\n\t\t\t\t1,\n\t\t\t\tthis.curContainer.alpha + delta / 60,\n\t\t\t);\n\t\t\tconst [s1, s2, s3, s4] = this.curContainer.children as Sprite[];\n\t\t\tconst maxSize = Math.max(this.app.screen.width, this.app.screen.height);\n\t\t\ts1.position.set(this.app.screen.width / 2, this.app.screen.height / 2);\n\t\t\ts2.position.set(\n\t\t\t\tthis.app.screen.width / 2.5,\n\t\t\t\tthis.app.screen.height / 2.5,\n\t\t\t);\n\t\t\ts3.position.set(this.app.screen.width / 2, this.app.screen.height / 2);\n\t\t\ts4.position.set(this.app.screen.width / 2, this.app.screen.height / 2);\n\t\t\ts1.width = maxSize * Math.sqrt(2);\n\t\t\ts1.height = s1.width;\n\t\t\ts2.width = maxSize * 0.8;\n\t\t\ts2.height = s2.width;\n\t\t\ts3.width = maxSize * 0.5;\n\t\t\ts3.height = s3.width;\n\t\t\ts4.width = maxSize * 0.25;\n\t\t\ts4.height = s4.width;\n\n\t\t\tthis.curContainer.time += delta * this.flowSpeed;\n\n\t\t\ts1.rotation += (delta / 1000) * this.flowSpeed;\n\t\t\ts2.rotation -= (delta / 500) * this.flowSpeed;\n\t\t\ts3.rotation += (delta / 1000) * this.flowSpeed;\n\t\t\ts4.rotation -= (delta / 750) * this.flowSpeed;\n\n\t\t\ts3.x =\n\t\t\t\tthis.app.screen.width / 2 +\n\t\t\t\t(this.app.screen.width / 4) *\n\t\t\t\t\tMath.cos((this.curContainer.time / 1000) * 0.75);\n\t\t\ts3.y =\n\t\t\t\tthis.app.screen.height / 2 +\n\t\t\t\t(this.app.screen.width / 4) *\n\t\t\t\t\tMath.cos((this.curContainer.time / 1000) * 0.75);\n\n\t\t\ts4.x =\n\t\t\t\tthis.app.screen.width / 2 +\n\t\t\t\t(this.app.screen.width / 4) * 0.1 +\n\t\t\t\tMath.cos(this.curContainer.time * 0.006 * 0.75);\n\t\t\ts4.y =\n\t\t\t\tthis.app.screen.height / 2 +\n\t\t\t\t(this.app.screen.width / 4) * 0.1 +\n\t\t\t\tMath.cos(this.curContainer.time * 0.006 * 0.75);\n\n\t\t\tif (\n\t\t\t\tthis.curContainer.alpha >= 1 &&\n\t\t\t\tthis.lastContainer.size === 0 &&\n\t\t\t\tthis.staticMode\n\t\t\t) {\n\t\t\t\tthis.app.ticker.stop();\n\t\t\t}\n\t\t}\n\t};\n\tconstructor(protected override canvas: HTMLCanvasElement) {\n\t\tsuper(canvas);\n\t\tthis.app = new Application({\n\t\t\tview: canvas,\n\t\t\tresizeTo: this.canvas,\n\t\t\tpowerPreference: \"low-power\",\n\t\t\tbackgroundAlpha: 1,\n\t\t});\n\t\tthis.rebuildFilters();\n\t\tthis.app.ticker.maxFPS = 30;\n\t\tthis.app.ticker.add(this.onTick);\n\t\tthis.app.ticker.start();\n\t}\n\n\tprotected override onResize(width: number, height: number): void {\n\t\tsuper.onResize(width, height);\n\t\tthis.app.resize();\n\t\tthis.rebuildFilters();\n\t}\n\n\toverride setRenderScale(scale: number): void {\n\t\tsuper.setRenderScale(scale);\n\t\tthis.rebuildFilters();\n\t}\n\tprivate rebuildFilters() {\n\t\tconst minBorder = Math.min(this.canvas.width, this.canvas.height);\n\t\tconst maxBorder = Math.max(this.canvas.width, this.canvas.height);\n\t\tconst c0 = new ColorMatrixFilter();\n\t\tc0.saturate(1.2, false);\n\t\tconst c1 = new ColorMatrixFilter();\n\t\tc1.brightness(0.6, false);\n\t\tconst c2 = new ColorMatrixFilter();\n\t\tc2.contrast(0.3, true);\n\t\tfor (const filter of this.app.stage.filters ?? []) {\n\t\t\tfilter.destroy();\n\t\t}\n\t\tthis.app.stage.filters = [];\n\t\tthis.app.stage.filters.push(new BlurFilter(5, 1));\n\t\tthis.app.stage.filters.push(new BlurFilter(10, 1));\n\t\tthis.app.stage.filters.push(new BlurFilter(20, 2));\n\t\tthis.app.stage.filters.push(new BlurFilter(40, 2));\n\t\tthis.app.stage.filters.push(new BlurFilter(80, 2));\n\t\tif (minBorder > 768) this.app.stage.filters.push(new BlurFilter(160, 4));\n\t\tif (minBorder > 768 * 2)\n\t\t\tthis.app.stage.filters.push(new BlurFilter(320, 4));\n\n\t\tthis.app.stage.filters.push(c0, c1, c2);\n\t\tthis.app.stage.filters.push(new BlurFilter(5, 1));\n\t\tif (Math.random() > 0.5) {\n\t\t\tthis.app.stage.filters.push(\n\t\t\t\tnew BulgePinchFilter({\n\t\t\t\t\tradius: (maxBorder + minBorder) / 2,\n\t\t\t\t\tstrength: 1,\n\t\t\t\t\tcenter: [0.25, 1],\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis.app.stage.filters.push(\n\t\t\t\tnew BulgePinchFilter({\n\t\t\t\t\tradius: (maxBorder + minBorder) / 2,\n\t\t\t\t\tstrength: 1,\n\t\t\t\t\tcenter: [0.75, 0],\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.app.stage.filters.push(\n\t\t\t\tnew BulgePinchFilter({\n\t\t\t\t\tradius: (maxBorder + minBorder) / 2,\n\t\t\t\t\tstrength: 1,\n\t\t\t\t\tcenter: [0.75, 1],\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis.app.stage.filters.push(\n\t\t\t\tnew BulgePinchFilter({\n\t\t\t\t\tradius: (maxBorder + minBorder) / 2,\n\t\t\t\t\tstrength: 1,\n\t\t\t\t\tcenter: [0.25, 0],\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\toverride setStaticMode(enable = false): void {\n\t\tthis.staticMode = enable;\n\t\tthis.app.ticker.start();\n\t}\n\n\toverride setFPS(fps: number): void {\n\t\tthis.app.ticker.maxFPS = fps;\n\t}\n\n\toverride pause(): void {\n\t\tthis.app.ticker.stop();\n\t\tthis.app.render();\n\t}\n\n\toverride resume(): void {\n\t\tthis.app.ticker.start();\n\t}\n\n\toverride setLowFreqVolume(_volume: number): void {\n\t\t// NOOP\n\t}\n\n\toverride setHasLyric(_hasLyric: boolean): void {\n\t\t// NOOP\n\t}\n\n\toverride async setAlbum(\n\t\talbumSource?: string | HTMLImageElement | HTMLVideoElement,\n\t\tisVideo?: boolean,\n\t): Promise<void> {\n\t\tif (\n\t\t\t!albumSource ||\n\t\t\t(typeof albumSource === \"string\" && albumSource.trim().length === 0)\n\t\t)\n\t\t\treturn;\n\t\tlet res: HTMLImageElement | HTMLVideoElement | null = null;\n\t\tlet remainRetryTimes = 5;\n\t\tlet tex: Texture | null = null;\n\t\twhile (!tex?.baseTexture?.resource?.valid && remainRetryTimes > 0) {\n\t\t\ttry {\n\t\t\t\tif (typeof albumSource === \"string\") {\n\t\t\t\t\tres = await loadResourceFromUrl(albumSource, isVideo);\n\t\t\t\t} else {\n\t\t\t\t\tres = await loadResourceFromElement(albumSource);\n\t\t\t\t}\n\t\t\t\ttex = Texture.from(res, {\n\t\t\t\t\tresourceOptions: {\n\t\t\t\t\t\tautoLoad: false,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tawait tex.baseTexture.resource.load();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`failed on loading album image, retrying (${remainRetryTimes})`,\n\t\t\t\t\talbumSource,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\ttex = null;\n\t\t\t\tremainRetryTimes--;\n\t\t\t}\n\t\t}\n\t\tif (!tex) return;\n\t\tconst container = new TimedContainer();\n\t\tconst s1 = new Sprite(tex);\n\t\tconst s2 = new Sprite(tex);\n\t\tconst s3 = new Sprite(tex);\n\t\tconst s4 = new Sprite(tex);\n\t\ts1.anchor.set(0.5, 0.5);\n\t\ts2.anchor.set(0.5, 0.5);\n\t\ts3.anchor.set(0.5, 0.5);\n\t\ts4.anchor.set(0.5, 0.5);\n\t\ts1.rotation = Math.random() * Math.PI * 2;\n\t\ts2.rotation = Math.random() * Math.PI * 2;\n\t\ts3.rotation = Math.random() * Math.PI * 2;\n\t\ts4.rotation = Math.random() * Math.PI * 2;\n\t\tcontainer.addChild(s1, s2, s3, s4);\n\t\tif (this.curContainer) this.lastContainer.add(this.curContainer);\n\t\tthis.curContainer = container;\n\t\tthis.app.stage.addChild(container);\n\t\tthis.curContainer.alpha = 0;\n\t\tthis.app.ticker.start();\n\t}\n\n\toverride dispose(): void {\n\t\tsuper.dispose();\n\t\tthis.app.ticker.remove(this.onTick);\n\t\tthis.app.destroy(true);\n\t}\n\n\toverride getElement(): HTMLElement {\n\t\treturn this.canvas;\n\t}\n}\n","/**\n * @fileoverview\n * 一个播放歌词的组件\n * @author SteveXMH\n */\n\nexport { AbstractBaseRenderer, BaseRenderer } from \"./base.ts\";\nexport { MeshGradientRenderer } from \"./mesh-renderer/index.ts\";\nexport { PixiRenderer } from \"./pixi-renderer.ts\";\nimport type { AbstractBaseRenderer, BaseRenderer } from \"./base.ts\";\n\nexport class BackgroundRender<Renderer extends BaseRenderer>\n\timplements AbstractBaseRenderer\n{\n\tprivate element: HTMLCanvasElement;\n\tprivate renderer: Renderer;\n\tconstructor(renderer: Renderer, canvas: HTMLCanvasElement) {\n\t\tthis.renderer = renderer;\n\n\t\tthis.element = canvas;\n\t\tcanvas.style.pointerEvents = \"none\";\n\t\tcanvas.style.zIndex = \"-1\";\n\t\tcanvas.style.contain = \"strict\";\n\t}\n\n\tstatic new<Renderer extends BaseRenderer>(type: {\n\t\tnew (canvas: HTMLCanvasElement): Renderer;\n\t}): BackgroundRender<Renderer> {\n\t\tconst newCanvas = document.createElement(\"canvas\");\n\t\treturn new BackgroundRender(new type(newCanvas), newCanvas);\n\t}\n\n\tsetRenderScale(scale: number): void {\n\t\tthis.renderer.setRenderScale(scale);\n\t}\n\n\tsetFlowSpeed(speed: number): void {\n\t\tthis.renderer.setFlowSpeed(speed);\n\t}\n\tsetStaticMode(enable: boolean): void {\n\t\tthis.renderer.setStaticMode(enable);\n\t}\n\tsetFPS(fps: number): void {\n\t\tthis.renderer.setFPS(fps);\n\t}\n\tpause(): void {\n\t\tthis.renderer.pause();\n\t}\n\tresume(): void {\n\t\tthis.renderer.resume();\n\t}\n\tsetLowFreqVolume(volume: number): void {\n\t\tthis.renderer.setLowFreqVolume(volume);\n\t}\n\tsetHasLyric(hasLyric: boolean): void {\n\t\tthis.renderer.setHasLyric(hasLyric);\n\t}\n\tsetAlbum(\n\t\talbumSource: string | HTMLImageElement | HTMLVideoElement,\n\t\tisVideo?: boolean,\n\t): Promise<void> {\n\t\treturn this.renderer.setAlbum(albumSource, isVideo);\n\t}\n\tgetElement(): HTMLCanvasElement {\n\t\treturn this.element;\n\t}\n\tdispose(): void {\n\t\tthis.renderer.dispose();\n\t\tthis.element.remove();\n\t}\n}\n","/*\n 给各个内部元素使用的样式\n*/\n\n/* 给每行歌词应用的样式 */\n.lyricLine {\n\tposition: absolute;\n\tbackface-visibility: hidden;\n\ttransform-origin: left;\n\twidth: var(--amll-lp-width, 100%);\n\tmin-width: var(--amll-lp-width, 100%);\n\tmax-width: var(--amll-lp-width, 100%);\n\twidth: 100%;\n\theight: fit-content;\n\tpadding: 0.5em 1em;\n\tcontain: content;\n\twill-change: transform;\n\ttransition:\n\t\topacity 0.25s,\n\t\tfilter 0.2s,\n\t\tbackground-color 0.25s,\n\t\tbox-shadow 0.25s;\n\tbox-sizing: border-box;\n\tborder-radius: 0.25em;\n\n\tpadding-left: 1em;\n\tpadding-right: 1em;\n\n\t@media screen and (max-width: 500px) {\n\t\tpadding-left: 20px;\n\t\tpadding-right: 20px;\n\t}\n\n\t&.dirty {\n\t\topacity: 0;\n\t\tvisibility: hidden;\n\t}\n\n\t&:has(> *):hover {\n\t\tbackground-color: var(--amll-lp-hover-bg-color, #fff1);\n\t\t/* box-shadow: 0 0 0 4px var(--amll-lp-hover-bg-color, #fff1); */\n\t}\n\n\t&:has(> *):active {\n\t\tbackground-color: var(--amll-lp-hover-bg-color, #ffffff05);\n\t\t/* box-shadow: 0 0 0 var(--amll-lp-hover-bg-color, #fff1); */\n\t}\n}\n\n.lyricBgLine {\n\topacity: 0.0001;\n\tfont-size: max(calc(1em * var(--amll-lp-bg-line-scale, 0.7)), 10px);\n\ttransition:\n\t\topacity 0.25s,\n\t\tscale 0.5s,\n\t\tfilter 0.2s,\n\t\tbackground-color 0.25s,\n\t\tbox-shadow 0.25s;\n\t/* 因为字体大小缩小了,故内边距要和主行字体大小统一,行边距计算公式为 100% / font-size 转 em 单位 */\n\tpadding: 1vh\n\t\tcalc(var(--amll-lp-line-padding-x, 1em) / var(--amll-lp-bg-line-scale, 0.7));\n\n\t&.active {\n\t\ttransition:\n\t\t\topacity 0.5s 0.25s,\n\t\t\tscale 1.5s cubic-bezier(0, 1, 0, 1) 0.25s,\n\t\t\tfilter 0.2s,\n\t\t\tbackground-color 0.25s,\n\t\t\tbox-shadow 0.25s;\n\t\topacity: 0.4;\n\t}\n}\n\n:global(.amll-lyric-player) {\n\t&:hover .lyricLine {\n\t\tfilter: unset !important;\n\t}\n\n\t&.hasDuetLine {\n\t\t.lyricLine:not(.lyricDuetLine) {\n\t\t\tpadding-right: 15%;\n\t\t}\n\n\t\t.lyricDuetLine {\n\t\t\tpadding-left: 15%;\n\t\t}\n\t}\n\n\t&:not(:global(.playing)) > .lyricBgLine {\n\t\topacity: 0.4;\n\t}\n}\n\n.lyricDuetLine {\n\ttext-align: right;\n\ttransform-origin: right;\n}\n\n.lyricMainLine {\n\ttransition: opacity 0.3s 0.1s;\n\tmargin: -1em;\n\tpadding: 1em;\n\n\ttext-wrap: balance;\n\n\tword-break: keep-all;\n\n\toverflow-wrap: break-word;\n\n\t& span {\n\t\tdisplay: inline-block;\n\t\ttext-align: start;\n\t\tvertical-align: bottom;\n\t}\n\n\t.romanWord {\n\t\tfont-size: 0.5em;\n\t\tline-height: 1em;\n\t\tdisplay: flex;\n\t\tpadding-inline-end: 0.3em;\n\t}\n\n\t.rubyWord {\n\t\tfont-size: 0.5em;\n\t\tline-height: 1em;\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\tmin-height: 1em;\n\t}\n\n\t.wordWithRuby {\n\t\tdisplay: inline-flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tvertical-align: bottom;\n\t}\n\n\t.wordBody {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t}\n\n\t& > span,\n\tspan.emphasizeWrapper {\n\t\twhite-space: pre-wrap;\n\t\tdisplay: inline-block;\n\t\tpadding: 1em;\n\t\tmargin: -1em;\n\t\twill-change: transform;\n\t\tvertical-align: bottom;\n\n\t\t&.emphasize,\n\t\tspan.emphasize {\n\t\t\tpadding: 1em;\n\t\t\tmargin: -1em;\n\t\t\tbackface-visibility: hidden;\n\n\t\t\t& > span {\n\t\t\t\tpadding: 1em;\n\t\t\t\tmargin: -1em;\n\t\t\t\twill-change: transform;\n\t\t\t\tbackface-visibility: hidden;\n\t\t\t}\n\t\t}\n\t}\n}\n\n.lyricSubLine {\n\tfont-size: max(0.5em, 10px);\n\tline-height: 1.5em;\n\ttransition: opacity 0.2s 0.25s;\n\topacity: 0.3;\n}\n\n.disableSpring > * {\n\ttransition:\n\t\tfilter 0.25s,\n\t\ttransform 0.5s,\n\t\tbackground-color 0.25s,\n\t\tbox-shadow 0.25s;\n}\n\n.interludeDots {\n\theight: clamp(0.5em, 1vh, 3em);\n\ttransition: opacity 0.25s;\n\ttransform-origin: center;\n\twidth: fit-content;\n\tpadding: 2.5% 0.75em;\n\tposition: absolute;\n\tdisplay: flex;\n\tgap: 0.25em;\n\tleft: 0;\n\topacity: 0;\n\n\t&.enabled {\n\t\topacity: 1;\n\t}\n\n\t& > * {\n\t\twidth: clamp(0.5em, 1vh, 3em);\n\t\theight: clamp(0.5em, 1vh, 3em);\n\t\tdisplay: inline-block;\n\t\tborder-radius: 50%;\n\t\taspect-ratio: 1 / 1;\n\t\tbackground-color: var(--amll-lp-color, white);\n\t\tmargin-right: 4px;\n\t}\n\n\t&.duet {\n\t\tright: 0;\n\t\ttransform-origin: center;\n\t}\n}\n\n@supports (mix-blend-mode: plus-lighter) {\n\t.lyricSubLine {\n\t\topacity: 0.3;\n\t}\n}\n\n.tmpDisableTransition {\n\ttransition: none !important;\n}\n\n.bottomLine {\n\tpadding-top: 0;\n\tpadding-bottom: 0;\n\tcursor: default;\n\tline-height: 1.8em;\n}\n\n.bottomLine:empty {\n\tdisplay: none;\n\tpadding: 0;\n\tmargin: 0;\n\theight: 0;\n}\n","export const eqSet: <T>(xs: Set<T>, ys: Set<T>) => boolean = (\n\txs,\n\tys,\n): boolean => xs.size === ys.size && [...xs].every((x) => ys.has(x));\n","export const isCJK = (char: string): boolean => {\n\treturn /^[\\p{Unified_Ideograph}\\u0800-\\u9FFC]+$/u.test(char);\n};\n","import type { LyricLine, OptimizeLyricOptions } from \"../interfaces.ts\";\n\nconst DEFAULT_OPTIMIZE_OPTIONS: OptimizeLyricOptions = {\n\tnormalizeSpaces: true,\n\tresetLineTimestamps: true,\n\tconvertExcessiveBackgroundLines: true,\n\tsyncMainAndBackgroundLines: true,\n\tcleanUnintentionalOverlaps: true,\n\ttryAdvanceStartTime: true,\n};\n\n/**\n * 规范化歌词中的空格,将多个连续空格替换为一个空格\n */\nfunction normalizeSpaces(lines: LyricLine[]) {\n\tfor (const line of lines) {\n\t\tfor (const word of line.words) {\n\t\t\tword.word = word.word.replace(/\\s+/g, \" \");\n\t\t}\n\t}\n}\n\n/**\n * 将行级时间戳强行设为字级时间戳\n */\nfunction resetLineTimestamps(lines: LyricLine[]) {\n\tfor (const line of lines) {\n\t\t// 主要是给 TTML 解析器打补丁,其解析逐行歌词时获得的词时间戳均为0\n\t\t// 如果只有一个词,且该词的起止时间均为0,且行时间戳不全为0,则将行时间戳同步给词时间戳\n\t\tif (\n\t\t\tline.words.length === 1 &&\n\t\t\tline.words[0].startTime === 0 &&\n\t\t\tline.words[0].endTime === 0 &&\n\t\t\t(line.startTime !== 0 || line.endTime !== 0)\n\t\t) {\n\t\t\tline.words[0].startTime = line.startTime;\n\t\t\tline.words[0].endTime = line.endTime;\n\t\t} else if (line.words.length > 0) {\n\t\t\tconst firstWord = line.words[0];\n\t\t\tconst lastWord = line.words[line.words.length - 1];\n\n\t\t\tline.startTime = firstWord.startTime;\n\t\t\tline.endTime = lastWord.endTime;\n\t\t}\n\t}\n}\n\n/**\n * 把多行背景人声转换为单行背景人声 + 主歌词行的形式\n */\nfunction convertExcessiveBackgroundLines(lines: LyricLine[]) {\n\tlet consecutiveBgCount = 0;\n\n\tfor (const line of lines) {\n\t\tif (line.isBG) {\n\t\t\tconsecutiveBgCount++;\n\t\t\tif (consecutiveBgCount > 1) {\n\t\t\t\tline.isBG = false;\n\t\t\t}\n\t\t} else {\n\t\t\tconsecutiveBgCount = 0;\n\t\t}\n\t}\n}\n\n/**\n * 同步主歌词与背景人声的时间\n *\n * 取两者中最早的开始时间和最晚的结束时间,应用给双方\n */\nfunction syncMainAndBackgroundLines(lines: LyricLine[]) {\n\tfor (let i = lines.length - 1; i >= 0; i--) {\n\t\tconst line = lines[i];\n\t\tif (line.isBG) continue;\n\n\t\tconst nextLine = lines[i + 1];\n\t\tif (nextLine?.isBG) {\n\t\t\tconst allWords = [...line.words, ...nextLine.words].filter(\n\t\t\t\t(w) => w.word.trim().length > 0,\n\t\t\t);\n\n\t\t\tif (allWords.length > 0) {\n\t\t\t\tconst minStart = Math.min(...allWords.map((w) => w.startTime));\n\t\t\t\tconst maxEnd = Math.max(...allWords.map((w) => w.endTime));\n\n\t\t\t\tconst finalStart = Math.min(\n\t\t\t\t\tminStart,\n\t\t\t\t\tline.startTime,\n\t\t\t\t\tnextLine.startTime,\n\t\t\t\t);\n\t\t\t\tconst finalEnd = Math.max(maxEnd, line.endTime, nextLine.endTime);\n\n\t\t\t\tline.startTime = finalStart;\n\t\t\t\tline.endTime = finalEnd;\n\t\t\t\tnextLine.startTime = finalStart;\n\t\t\t\tnextLine.endTime = finalEnd;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * 清洗非刻意的重叠\n *\n * 如果重叠大于100ms 且 重叠超过下一行时长的10%,则视为刻意重叠,否则将结束时间设为下一行的开始时间\n */\nfunction cleanUnintentionalOverlaps(lines: LyricLine[]) {\n\tfor (let i = 0; i < lines.length - 1; i++) {\n\t\tconst line = lines[i];\n\t\tif (line.isBG) continue;\n\n\t\tlet nextMainIndex = i + 1;\n\t\twhile (nextMainIndex < lines.length && lines[nextMainIndex].isBG) {\n\t\t\tnextMainIndex++;\n\t\t}\n\n\t\tif (nextMainIndex < lines.length) {\n\t\t\tconst nextLine = lines[nextMainIndex];\n\t\t\tconst overlap = line.endTime - nextLine.startTime;\n\n\t\t\tif (overlap > 0) {\n\t\t\t\tconst nextDuration = nextLine.endTime - nextLine.startTime;\n\t\t\t\tconst percentageThreshold = nextDuration * 0.1;\n\n\t\t\t\t// 重叠大于100ms 且 重叠超过下一行时长的10%\n\t\t\t\tconst isIntentionalOverlap =\n\t\t\t\t\toverlap > 100 && overlap > percentageThreshold;\n\n\t\t\t\tif (!isIntentionalOverlap) {\n\t\t\t\t\tline.endTime = nextLine.startTime;\n\n\t\t\t\t\tconst attachedBgLine = lines[i + 1];\n\t\t\t\t\tif (attachedBgLine?.isBG) {\n\t\t\t\t\t\tattachedBgLine.endTime = nextLine.startTime;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * 尝试让歌词提前最多 600ms 开始,如果有重叠则尝试最多提前 400ms 或上一行时长的 30%\n */\nfunction tryAdvanceStartTime(lines: LyricLine[]) {\n\tfor (let i = lines.length - 1; i >= 0; i--) {\n\t\tconst line = lines[i];\n\t\tif (line.isBG) continue;\n\n\t\tlet prevLine: LyricLine | null = null;\n\t\tif (i > 0) {\n\t\t\tlet prevIdx = i - 1;\n\t\t\tif (lines[prevIdx].isBG) {\n\t\t\t\tprevIdx--;\n\t\t\t}\n\t\t\tif (prevIdx >= 0) {\n\t\t\t\tprevLine = lines[prevIdx];\n\t\t\t}\n\t\t}\n\n\t\tlet targetAdvanceAmount = 0;\n\t\tlet safeBoundary = 0;\n\n\t\tif (prevLine) {\n\t\t\tconst originallyHadGap = line.startTime >= prevLine.endTime;\n\n\t\t\tif (originallyHadGap) {\n\t\t\t\ttargetAdvanceAmount = 600;\n\t\t\t\tsafeBoundary = prevLine.endTime;\n\t\t\t} else {\n\t\t\t\ttargetAdvanceAmount = 400;\n\t\t\t\tconst prevDuration = prevLine.endTime - prevLine.startTime;\n\t\t\t\tsafeBoundary = prevLine.startTime + prevDuration * 0.3;\n\t\t\t}\n\t\t} else {\n\t\t\ttargetAdvanceAmount = 600;\n\t\t\tsafeBoundary = 0;\n\t\t}\n\n\t\tconst targetTime = line.startTime - targetAdvanceAmount;\n\t\tconst newStartTime = Math.max(safeBoundary, targetTime);\n\n\t\tif (newStartTime < line.startTime) {\n\t\t\tline.startTime = newStartTime;\n\t\t}\n\n\t\tconst nextLine = lines[i + 1];\n\t\tif (nextLine?.isBG) {\n\t\t\tnextLine.startTime = line.startTime;\n\t\t}\n\t}\n}\n\n/**\n * 优化歌词行的展示效果\n *\n * 注意会直接原地修改入参,确保你已经提前深克隆了歌词行数组\n * @param lines 歌词行数组\n * @param options 优化的可选配置,默认全部开启\n */\nexport function optimizeLyricLines(\n\tlines: LyricLine[],\n\toptions?: OptimizeLyricOptions,\n): void {\n\tconst config = { ...DEFAULT_OPTIMIZE_OPTIONS, ...options };\n\n\tif (config.normalizeSpaces) {\n\t\tnormalizeSpaces(lines);\n\t}\n\tif (config.resetLineTimestamps) {\n\t\tresetLineTimestamps(lines);\n\t}\n\tif (config.convertExcessiveBackgroundLines) {\n\t\tconvertExcessiveBackgroundLines(lines);\n\t}\n\tif (config.syncMainAndBackgroundLines) {\n\t\tsyncMainAndBackgroundLines(lines);\n\t}\n\tif (config.cleanUnintentionalOverlaps) {\n\t\tcleanUnintentionalOverlaps(lines);\n\t}\n\tif (config.tryAdvanceStartTime) {\n\t\ttryAdvanceStartTime(lines);\n\t}\n}\n","export function derivative(f: (x: number) => number) {\n\tconst h = 0.001;\n\treturn (x: number): number => (f(x + h) - f(x - h)) / (2 * h);\n}\n\nexport function getVelocity(f: (t: number) => number): (t: number) => number {\n\treturn derivative(f);\n}\n","import { getVelocity } from \"./derivative.ts\";\n\n/** MIT License github.com/pushkine/ */\nexport interface SpringParams {\n\tmass: number; // = 1.0\n\tdamping: number; // = 10.0\n\tstiffness: number; // = 100.0\n\tsoft: boolean; // = false\n}\n\ntype seconds = number;\n\nexport class Spring {\n\tprivate currentPosition = 0;\n\tprivate targetPosition = 0;\n\tprivate currentTime = 0;\n\tprivate params: Partial<SpringParams> = {};\n\tprivate currentSolver: (t: seconds) => number;\n\tprivate getV: (t: seconds) => number;\n\tprivate getV2: (t: seconds) => number;\n\tprivate queueParams:\n\t\t| (Partial<SpringParams> & {\n\t\t\t\ttime: number;\n\t\t })\n\t\t| undefined;\n\tprivate queuePosition:\n\t\t| {\n\t\t\t\ttime: number;\n\t\t\t\tposition: number;\n\t\t }\n\t\t| undefined;\n\tconstructor(currentPosition = 0) {\n\t\tthis.targetPosition = currentPosition;\n\t\tthis.currentPosition = this.targetPosition;\n\t\tthis.currentSolver = () => this.targetPosition;\n\t\tthis.getV = () => 0;\n\t\tthis.getV2 = () => 0;\n\t}\n\tprivate resetSolver() {\n\t\tconst curV = this.getV(this.currentTime);\n\t\tthis.currentTime = 0;\n\t\tthis.currentSolver = solveSpring(\n\t\t\tthis.currentPosition,\n\t\t\tcurV,\n\t\t\tthis.targetPosition,\n\t\t\t0,\n\t\t\tthis.params,\n\t\t);\n\t\tthis.getV = getVelocity(this.currentSolver);\n\t\tthis.getV2 = getVelocity(this.getV);\n\t}\n\tarrived(): boolean {\n\t\treturn (\n\t\t\tMath.abs(this.targetPosition - this.currentPosition) < 0.01 &&\n\t\t\tthis.getV(this.currentTime) < 0.01 &&\n\t\t\tthis.getV2(this.currentTime) < 0.01 &&\n\t\t\tthis.queueParams === undefined &&\n\t\t\tthis.queuePosition === undefined\n\t\t);\n\t}\n\tsetPosition(targetPosition: number): void {\n\t\tthis.targetPosition = targetPosition;\n\t\tthis.currentPosition = targetPosition;\n\t\tthis.currentSolver = () => this.targetPosition;\n\t\tthis.getV = () => 0;\n\t\tthis.getV2 = () => 0;\n\t}\n\tupdate(delta = 0): void {\n\t\tthis.currentTime += delta;\n\t\tthis.currentPosition = this.currentSolver(this.currentTime);\n\t\tif (this.queueParams) {\n\t\t\tthis.queueParams.time -= delta;\n\t\t\tif (this.queueParams.time <= 0) {\n\t\t\t\tthis.updateParams({\n\t\t\t\t\t...this.queueParams,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (this.queuePosition) {\n\t\t\tthis.queuePosition.time -= delta;\n\t\t\tif (this.queuePosition.time <= 0) {\n\t\t\t\tthis.setTargetPosition(this.queuePosition.position);\n\t\t\t}\n\t\t}\n\t\tif (this.arrived()) {\n\t\t\tthis.setPosition(this.targetPosition);\n\t\t}\n\t}\n\tupdateParams(params: Partial<SpringParams>, delay = 0): void {\n\t\tif (delay > 0) {\n\t\t\tthis.queueParams = {\n\t\t\t\t...(this.queuePosition ?? {}),\n\t\t\t\t...params,\n\t\t\t\ttime: delay,\n\t\t\t};\n\t\t} else {\n\t\t\tthis.queuePosition = undefined;\n\t\t\tthis.params = {\n\t\t\t\t...this.params,\n\t\t\t\t...params,\n\t\t\t};\n\t\t\tthis.resetSolver();\n\t\t}\n\t}\n\tsetTargetPosition(targetPosition: number, delay = 0): void {\n\t\tif (delay > 0) {\n\t\t\tthis.queuePosition = {\n\t\t\t\t...(this.queuePosition ?? {}),\n\t\t\t\tposition: targetPosition,\n\t\t\t\ttime: delay,\n\t\t\t};\n\t\t} else {\n\t\t\tthis.queuePosition = undefined;\n\t\t\tthis.targetPosition = targetPosition;\n\t\t\tthis.resetSolver();\n\t\t}\n\t}\n\tgetCurrentPosition(): number {\n\t\treturn this.currentPosition;\n\t}\n}\n\nfunction solveSpring(\n\tfrom: number,\n\tvelocity: number,\n\tto: number,\n\tdelay: seconds = 0,\n\tparams?: Partial<SpringParams>,\n): (t: seconds) => number {\n\tconst soft = params?.soft ?? false;\n\tconst stiffness = params?.stiffness ?? 100;\n\tconst damping = params?.damping ?? 10;\n\tconst mass = params?.mass ?? 1;\n\tconst delta = to - from;\n\tif (soft || 1.0 <= damping / (2.0 * Math.sqrt(stiffness * mass))) {\n\t\tconst angular_frequency = -Math.sqrt(stiffness / mass);\n\t\tconst leftover = -angular_frequency * delta - velocity;\n\t\treturn (t: seconds) => {\n\t\t\tt -= delay;\n\t\t\tif (t < 0) return from;\n\t\t\treturn to - (delta + t * leftover) * Math.E ** (t * angular_frequency);\n\t\t};\n\t}\n\tconst damping_frequency = Math.sqrt(4.0 * mass * stiffness - damping ** 2.0);\n\tconst leftover =\n\t\t(damping * delta - 2.0 * mass * velocity) / damping_frequency;\n\tconst dfm = (0.5 * damping_frequency) / mass;\n\tconst dm = -(0.5 * damping) / mass;\n\treturn (t: seconds) => {\n\t\tt -= delay;\n\t\tif (t < 0) return from;\n\t\treturn (\n\t\t\tto -\n\t\t\t(Math.cos(t * dfm) * delta + Math.sin(t * dfm) * leftover) *\n\t\t\t\tMath.E ** (t * dm)\n\t\t);\n\t};\n}\n","/**\n * @fileoverview\n * @see https://github.com/wilsonpage/fastdom/blob/master/fastdom.js\n */\n\ninterface Task<T> {\n\ttask: () => T;\n\tresolve: (value: T) => void;\n\treject: (reason?: unknown) => void;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: util functions\nconst measureTasks: Task<any>[] = [];\n// biome-ignore lint/suspicious/noExplicitAny: util functions\nconst mutateTasks: Task<any>[] = [];\nlet scheduled = false;\n\nfunction onFlush() {\n\tlet tmp = mutateTasks.shift();\n\twhile (tmp) {\n\t\ttry {\n\t\t\ttmp.resolve(tmp.task());\n\t\t} catch (error) {\n\t\t\ttmp.reject(error);\n\t\t}\n\t\ttmp = mutateTasks.shift();\n\t}\n\ttmp = measureTasks.shift();\n\twhile (tmp) {\n\t\ttry {\n\t\t\ttmp.resolve(tmp.task());\n\t\t} catch (error) {\n\t\t\ttmp.reject(error);\n\t\t}\n\t\ttmp = measureTasks.shift();\n\t}\n\tscheduled = false;\n}\n\nfunction scheduleFlush() {\n\tif (!scheduled) {\n\t\tscheduled = true;\n\t\trequestAnimationFrame(onFlush);\n\t}\n}\n\nexport function measure<T>(callback: () => T): Promise<T> {\n\tconst task: Task<T> = {\n\t\ttask: callback,\n\t\tresolve: () => {},\n\t\treject: () => {},\n\t};\n\tconst promise = new Promise<T>((resolve, reject) => {\n\t\ttask.resolve = resolve;\n\t\ttask.reject = reject;\n\t});\n\tmeasureTasks.push(task);\n\tscheduleFlush();\n\treturn promise;\n}\n\nexport function mutate(callback: () => void): Promise<unknown> {\n\tconst task: Task<void> = {\n\t\ttask: callback,\n\t\tresolve: () => {},\n\t\treject: () => {},\n\t};\n\tconst promise = new Promise((resolve, reject) => {\n\t\ttask.resolve = resolve;\n\t\ttask.reject = reject;\n\t});\n\tmutateTasks.push(task);\n\tscheduleFlush();\n\treturn promise;\n}\n","import type { Disposable, HasElement } from \"../interfaces.ts\";\nimport styles from \"../styles/lyric-player.module.css\";\nimport { measure } from \"../utils/schedule.ts\";\nimport { Spring } from \"../utils/spring.ts\";\nimport type { LyricPlayerBase } from \"./base.ts\";\n\ninterface LineTransforms {\n\tposX: Spring;\n\tposY: Spring;\n}\n\nexport class BottomLineEl implements HasElement, Disposable {\n\tprivate element: HTMLElement = document.createElement(\"div\");\n\tprivate left = 0;\n\tprivate top = 0;\n\tprivate delay = 0;\n\t// 由 LyricPlayer 来设置\n\tlineSize: [number, number] = [0, 0];\n\treadonly lineTransforms: LineTransforms = {\n\t\tposX: new Spring(0),\n\t\tposY: new Spring(0),\n\t};\n\tprivate isFocused = false;\n\tprivate blur = 0;\n\tconstructor(private lyricPlayer: LyricPlayerBase) {\n\t\tthis.element.setAttribute(\n\t\t\t\"class\",\n\t\t\t`${styles.lyricLine} ${styles.bottomLine}`,\n\t\t);\n\t\tthis.element.dataset.bottomLine = \"true\";\n\t\tthis.rebuildStyle();\n\t}\n\tasync measureSize(): Promise<[number, number]> {\n\t\tconst size: [number, number] = await measure(() => [\n\t\t\tthis.element.clientWidth,\n\t\t\tthis.element.clientHeight,\n\t\t]);\n\t\treturn size;\n\t}\n\tprivate lastStyle = \"\";\n\tshow(): void {\n\t\tthis.rebuildStyle();\n\t}\n\thide(): void {\n\t\tthis.rebuildStyle();\n\t}\n\tsetFocused(focused: boolean): void {\n\t\tif (this.isFocused !== focused) {\n\t\t\tthis.isFocused = focused;\n\t\t\tif (focused) {\n\t\t\t\tthis.element.dataset.focused = \"true\";\n\t\t\t} else {\n\t\t\t\tdelete this.element.dataset.focused;\n\t\t\t}\n\t\t}\n\t}\n\tprivate rebuildStyle() {\n\t\tlet style = `transform:translate(${this.lineTransforms.posX\n\t\t\t.getCurrentPosition()\n\t\t\t.toFixed(2)}px,${this.lineTransforms.posY\n\t\t\t.getCurrentPosition()\n\t\t\t.toFixed(2)}px);`;\n\n\t\tif (!this.lyricPlayer.getEnableSpring() && this.isInSight) {\n\t\t\tstyle += `transition-delay:${this.delay}ms;`;\n\t\t}\n\n\t\tstyle += `filter:blur(${Math.min(5, this.blur)}px);`;\n\n\t\tif (style !== this.lastStyle) {\n\t\t\tthis.lastStyle = style;\n\t\t\tthis.element.setAttribute(\"style\", style);\n\t\t}\n\t}\n\tgetElement(): HTMLElement {\n\t\treturn this.element;\n\t}\n\tsetTransform(\n\t\tleft: number = this.left,\n\t\ttop: number = this.top,\n\t\tblur = 0,\n\t\tforce = false,\n\t\tdelay = 0,\n\t): void {\n\t\tthis.left = left;\n\t\tthis.top = top;\n\t\tthis.delay = (delay * 1000) | 0;\n\n\t\tif (force || !this.lyricPlayer.getEnableSpring()) {\n\t\t\tthis.blur = Math.min(32, blur);\n\t\t\tif (force) this.element.classList.add(styles.tmpDisableTransition);\n\t\t\tthis.lineTransforms.posX.setPosition(left);\n\t\t\tthis.lineTransforms.posY.setPosition(top);\n\t\t\tif (!this.lyricPlayer.getEnableSpring()) this.show();\n\t\t\telse this.rebuildStyle();\n\t\t\tif (force)\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tthis.element.classList.remove(styles.tmpDisableTransition);\n\t\t\t\t});\n\t\t} else {\n\t\t\tthis.blur = Math.min(5, blur);\n\t\t\tthis.lineTransforms.posX.setTargetPosition(left, delay);\n\t\t\tthis.lineTransforms.posY.setTargetPosition(top, delay);\n\t\t}\n\t}\n\tupdate(delta = 0): void {\n\t\tif (!this.lyricPlayer.getEnableSpring()) return;\n\t\tthis.lineTransforms.posX.update(delta);\n\t\tthis.lineTransforms.posY.update(delta);\n\t\tif (this.isInSight) {\n\t\t\tthis.show();\n\t\t} else {\n\t\t\tthis.hide();\n\t\t}\n\t}\n\tget isInSight(): boolean {\n\t\tconst l = this.lineTransforms.posX.getCurrentPosition();\n\t\tconst t = this.lineTransforms.posY.getCurrentPosition();\n\t\tconst r = l + this.lineSize[0];\n\t\tconst b = t + this.lineSize[1];\n\t\tconst pr = this.lyricPlayer.size[0];\n\t\tconst pb = this.lyricPlayer.size[1];\n\t\treturn !(l > pr || t > pb || r < 0 || b < 0);\n\t}\n\tdispose(): void {\n\t\tthis.element.remove();\n\t}\n}\n","import type { Disposable, HasElement } from \"../../interfaces.ts\";\nimport styles from \"../../styles/lyric-player.module.css\";\n\nfunction easeInOutBack(x: number): number {\n\tconst c1 = 1.70158;\n\tconst c2 = c1 * 1.525;\n\n\treturn x < 0.5\n\t\t? ((2 * x) ** 2 * ((c2 + 1) * 2 * x - c2)) / 2\n\t\t: ((2 * x - 2) ** 2 * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;\n}\n\nfunction easeOutExpo(x: number): number {\n\treturn x === 1 ? 1 : 1 - 2 ** (-10 * x);\n}\n\nconst clamp = (min: number, cur: number, max: number) =>\n\tMath.max(min, Math.min(cur, max));\n\nexport class InterludeDots implements HasElement, Disposable {\n\tprivate element: HTMLElement = document.createElement(\"div\");\n\tprivate dot0: HTMLElement = document.createElement(\"span\");\n\tprivate dot1: HTMLElement = document.createElement(\"span\");\n\tprivate dot2: HTMLElement = document.createElement(\"span\");\n\tprivate left = 0;\n\tprivate top = 0;\n\tprivate playing = true;\n\tprivate lastStyle = \"\";\n\tprivate currentInterlude?: [number, number];\n\tprivate currentTime = 0;\n\tprivate targetBreatheDuration = 1500;\n\tconstructor() {\n\t\tthis.element.className = styles.interludeDots;\n\t\tthis.element.appendChild(this.dot0);\n\t\tthis.element.appendChild(this.dot1);\n\t\tthis.element.appendChild(this.dot2);\n\t}\n\tgetElement(): HTMLElement {\n\t\treturn this.element;\n\t}\n\tsetTransform(left: number = this.left, top: number = this.top): void {\n\t\tthis.left = left;\n\t\tthis.top = top;\n\t\tthis.update();\n\t}\n\tsetInterlude(interlude?: [number, number]): void {\n\t\tthis.currentInterlude = interlude;\n\t\tthis.currentTime = interlude?.[0] ?? 0;\n\t\tif (interlude) {\n\t\t\tthis.element.classList.add(styles.enabled);\n\t\t} else {\n\t\t\tthis.element.classList.remove(styles.enabled);\n\t\t}\n\t}\n\tpause(): void {\n\t\tthis.playing = false;\n\t\tthis.element.classList.remove(styles.playing);\n\t}\n\tresume(): void {\n\t\tthis.playing = true;\n\t\tthis.element.classList.add(styles.playing);\n\t}\n\tupdate(delta = 0): void {\n\t\tif (!this.playing) return;\n\t\tthis.currentTime += delta;\n\t\tlet curStyle = \"\";\n\n\t\tcurStyle += `transform:translate(${this.left.toFixed(\n\t\t\t2,\n\t\t)}px, ${this.top.toFixed(2)}px)`;\n\n\t\t// 计算缩放大小\n\n\t\tif (this.currentInterlude) {\n\t\t\tconst interludeDuration =\n\t\t\t\tthis.currentInterlude[1] - this.currentInterlude[0];\n\t\t\tconst currentDuration = this.currentTime - this.currentInterlude[0];\n\t\t\tif (currentDuration <= interludeDuration) {\n\t\t\t\tconst breatheDuration =\n\t\t\t\t\tinterludeDuration /\n\t\t\t\t\tMath.ceil(interludeDuration / this.targetBreatheDuration);\n\t\t\t\tlet scale = 1;\n\t\t\t\tlet globalOpacity = 1;\n\n\t\t\t\tscale *=\n\t\t\t\t\tMath.sin(1.5 * Math.PI - (currentDuration / breatheDuration) * 2) /\n\t\t\t\t\t\t20 +\n\t\t\t\t\t1;\n\n\t\t\t\tif (currentDuration < 2000) {\n\t\t\t\t\tscale *= easeOutExpo(currentDuration / 2000);\n\t\t\t\t}\n\n\t\t\t\tif (currentDuration < 500) {\n\t\t\t\t\tglobalOpacity = 0;\n\t\t\t\t} else if (currentDuration < 1000) {\n\t\t\t\t\tglobalOpacity *= (currentDuration - 500) / 500;\n\t\t\t\t}\n\n\t\t\t\tif (interludeDuration - currentDuration < 750) {\n\t\t\t\t\tscale *=\n\t\t\t\t\t\t1 -\n\t\t\t\t\t\teaseInOutBack(\n\t\t\t\t\t\t\t(750 - (interludeDuration - currentDuration)) / 750 / 2,\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (interludeDuration - currentDuration < 375) {\n\t\t\t\t\tglobalOpacity *= clamp(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t(interludeDuration - currentDuration) / 375,\n\t\t\t\t\t\t1,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst dotsDuration = Math.max(0, interludeDuration - 750);\n\n\t\t\t\tscale = Math.max(0, scale) * 0.7;\n\n\t\t\t\tcurStyle += ` scale(${scale})`;\n\n\t\t\t\tconst dot0Opacity = clamp(\n\t\t\t\t\t0.25,\n\t\t\t\t\t((currentDuration * 3) / dotsDuration) * 0.75,\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t\tconst dot1Opacity = clamp(\n\t\t\t\t\t0.25,\n\t\t\t\t\t(((currentDuration - dotsDuration / 3) * 3) / dotsDuration) * 0.75,\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t\tconst dot2Opacity = clamp(\n\t\t\t\t\t0.25,\n\t\t\t\t\t(((currentDuration - (dotsDuration / 3) * 2) * 3) / dotsDuration) *\n\t\t\t\t\t\t0.75,\n\t\t\t\t\t1,\n\t\t\t\t);\n\n\t\t\t\tthis.dot0.style.opacity = `${clamp(\n\t\t\t\t\t0,\n\t\t\t\t\tMath.max(0, globalOpacity * dot0Opacity),\n\t\t\t\t\t1,\n\t\t\t\t)}`;\n\t\t\t\tthis.dot1.style.opacity = `${clamp(\n\t\t\t\t\t0,\n\t\t\t\t\tMath.max(0, globalOpacity * dot1Opacity),\n\t\t\t\t\t1,\n\t\t\t\t)}`;\n\t\t\t\tthis.dot2.style.opacity = `${clamp(\n\t\t\t\t\t0,\n\t\t\t\t\tMath.max(0, globalOpacity * dot2Opacity),\n\t\t\t\t\t1,\n\t\t\t\t)}`;\n\t\t\t} else {\n\t\t\t\tcurStyle += \" scale(0)\";\n\t\t\t\tthis.dot0.style.opacity = \"0\";\n\t\t\t\tthis.dot1.style.opacity = \"0\";\n\t\t\t\tthis.dot2.style.opacity = \"0\";\n\t\t\t}\n\n\t\t\tcurStyle += \";\";\n\n\t\t\tif (this.lastStyle !== curStyle) {\n\t\t\t\tthis.element.setAttribute(\"style\", curStyle);\n\t\t\t\tthis.lastStyle = curStyle;\n\t\t\t}\n\t\t}\n\t}\n\tdispose(): void {\n\t\tthis.element.remove();\n\t}\n}\n","import structuredClone from \"@ungap/structured-clone\";\nimport type {\n\tDisposable,\n\tHasElement,\n\tLyricLine,\n\tLyricWord,\n\tOptimizeLyricOptions,\n} from \"../interfaces.ts\";\nimport styles from \"../styles/lyric-player.module.css\";\nimport { eqSet } from \"../utils/eq-set.ts\";\nimport { isCJK } from \"../utils/is-cjk.ts\";\nimport { optimizeLyricLines } from \"../utils/optimize-lyric.ts\";\nimport { Spring, type SpringParams } from \"../utils/spring.ts\";\nimport { BottomLineEl } from \"./bottom-line.ts\";\nimport { InterludeDots } from \"./dom/interlude-dots.ts\";\nimport { LyricLineRenderMode, MaskObsceneWordsMode } from \"./index.ts\";\n\n/**\n * 歌词播放器的基类,已经包含了有关歌词操作和排版的功能,子类需要为其实现对应的显示展示操作\n */\nexport abstract class LyricPlayerBase\n\textends EventTarget\n\timplements HasElement, Disposable\n{\n\tprotected element: HTMLElement = document.createElement(\"div\");\n\tabstract get baseFontSize(): number;\n\n\tprotected currentTime = 0;\n\t/** @internal */\n\tlyricLinesSize: WeakMap<LyricLineBase, [number, number]> = new WeakMap();\n\t/** @internal */\n\tlyricLineElementMap: WeakMap<Element, LyricLineBase> = new WeakMap();\n\tprotected currentLyricLines: LyricLine[] = [];\n\t// protected currentLyricLineObjects: LyricLineBase[] = [];\n\tprotected processedLines: LyricLine[] = [];\n\tprotected lyricLinesIndexes: WeakMap<LyricLineBase, number> = new WeakMap();\n\tprotected hotLines: Set<number> = new Set();\n\tprotected bufferedLines: Set<number> = new Set();\n\tprotected isNonDynamic = false;\n\tprotected hasDuetLine = false;\n\tprotected scrollToIndex = 0;\n\tprotected disableSpring = false;\n\tprotected interludeDotsSize: [number, number] = [0, 0];\n\tprotected interludeDots: InterludeDots = new InterludeDots();\n\tprotected bottomLine: BottomLineEl = new BottomLineEl(this);\n\tprotected enableBlur = true;\n\tprotected enableScale = true;\n\tprotected maskObsceneWords: MaskObsceneWordsMode =\n\t\tMaskObsceneWordsMode.Disabled;\n\tprotected maskObsceneWordChar = \"*\";\n\tprotected hidePassedLines = false;\n\tprotected scrollBoundary: [number, number] = [0, 0];\n\tprotected currentLyricLineObjects: LyricLineBase[] = [];\n\tprotected isSeeking = false;\n\tprotected lastCurrentTime = 0;\n\tprotected alignAnchor: \"top\" | \"bottom\" | \"center\" = \"center\";\n\tprotected alignPosition = 0.35;\n\tprotected scrollOffset = 0;\n\treadonly size: [number, number] = [0, 0];\n\tprotected allowScroll = true;\n\tprotected isPageVisible = true;\n\tprotected optimizeOptions: OptimizeLyricOptions = {};\n\n\tprotected initialLayoutFinished = false;\n\n\t/**\n\t * 标记用户是否正在进行滚动交互\n\t */\n\tprotected isUserScrolling = false;\n\tprotected wheelTimeout: ReturnType<typeof setTimeout> | undefined;\n\n\t/**\n\t * 视图额外预渲染(overscan)距离,单位:像素。\n\t * 用于决定在视口之外多少距离内也认为是“可见”,以便提前创建/保留行元素。\n\t */\n\tprotected overscanPx = 300;\n\n\tprotected posXSpringParams: Partial<SpringParams> = {\n\t\tmass: 1,\n\t\tdamping: 10,\n\t\tstiffness: 100,\n\t};\n\tprotected posYSpringParams: Partial<SpringParams> = {\n\t\tmass: 0.9,\n\t\tdamping: 15,\n\t\tstiffness: 90,\n\t};\n\tprotected scaleSpringParams: Partial<SpringParams> = {\n\t\tmass: 2,\n\t\tdamping: 25,\n\t\tstiffness: 100,\n\t};\n\tprotected scaleForBGSpringParams: Partial<SpringParams> = {\n\t\tmass: 1,\n\t\tdamping: 20,\n\t\tstiffness: 50,\n\t};\n\tprivate onPageShow = () => {\n\t\tthis.isPageVisible = true;\n\t\tthis.setCurrentTime(this.currentTime, true);\n\t};\n\tprivate onPageHide = () => {\n\t\tthis.isPageVisible = false;\n\t};\n\tprivate scrolledHandler: ReturnType<typeof setTimeout> | undefined;\n\tprotected isScrolled = false;\n\t/** @internal */\n\tresizeObserver: ResizeObserver = new ResizeObserver(((entries) => {\n\t\tlet shouldRelayout = false;\n\t\tlet shouldRebuildPlayerStyle = false;\n\t\tfor (const entry of entries) {\n\t\t\tif (entry.target === this.element) {\n\t\t\t\tconst rect = entry.contentRect;\n\t\t\t\tthis.size[0] = rect.width;\n\t\t\t\tthis.size[1] = rect.height;\n\t\t\t\tshouldRebuildPlayerStyle = true;\n\t\t\t} else if (entry.target === this.interludeDots.getElement()) {\n\t\t\t\tthis.interludeDotsSize[0] = entry.target.clientWidth;\n\t\t\t\tthis.interludeDotsSize[1] = entry.target.clientHeight;\n\t\t\t\tshouldRelayout = true;\n\t\t\t} else if (entry.target === this.bottomLine.getElement()) {\n\t\t\t\tconst newSize: [number, number] = [\n\t\t\t\t\tentry.target.clientWidth,\n\t\t\t\t\tentry.target.clientHeight,\n\t\t\t\t];\n\t\t\t\tconst oldSize: [number, number] = this.bottomLine.lineSize;\n\n\t\t\t\tif (newSize[0] !== oldSize[0] || newSize[1] !== oldSize[1]) {\n\t\t\t\t\tthis.bottomLine.lineSize = newSize;\n\t\t\t\t\tshouldRelayout = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst lineObj = this.lyricLineElementMap.get(entry.target);\n\t\t\t\tif (lineObj) {\n\t\t\t\t\tconst newSize: [number, number] = [\n\t\t\t\t\t\tentry.target.clientWidth,\n\t\t\t\t\t\tentry.target.clientHeight,\n\t\t\t\t\t];\n\t\t\t\t\tconst oldSize: [number, number] = this.lyricLinesSize.get(\n\t\t\t\t\t\tlineObj,\n\t\t\t\t\t) ?? [0, 0];\n\n\t\t\t\t\tif (newSize[0] !== oldSize[0] || newSize[1] !== oldSize[1]) {\n\t\t\t\t\t\tthis.lyricLinesSize.set(lineObj, newSize);\n\t\t\t\t\t\tlineObj.onLineSizeChange(newSize);\n\t\t\t\t\t\tshouldRelayout = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (shouldRelayout) {\n\t\t\tthis.calcLayout(true);\n\t\t}\n\t\tif (shouldRebuildPlayerStyle) {\n\t\t\tthis.onResize();\n\t\t}\n\t}) as ResizeObserverCallback);\n\tprotected wordFadeWidth = 0.5;\n\tprotected targetAlignIndex = 0;\n\tprotected lastInterludeState = false;\n\n\tconstructor(element?: HTMLElement) {\n\t\tsuper();\n\t\tif (element) this.element = element;\n\t\tthis.element.classList.add(\"amll-lyric-player\");\n\n\t\tthis.resizeObserver.observe(this.element);\n\t\tthis.resizeObserver.observe(this.interludeDots.getElement());\n\n\t\tthis.element.appendChild(this.interludeDots.getElement());\n\t\tthis.element.appendChild(this.bottomLine.getElement());\n\t\tthis.interludeDots.setTransform(0, 200);\n\n\t\twindow.addEventListener(\"pageshow\", this.onPageShow);\n\t\twindow.addEventListener(\"pagehide\", this.onPageHide);\n\n\t\tlet startScrollY = 0;\n\n\t\tlet startTouchPosY = 0;\n\t\tlet startTouchStartX = 0;\n\t\tlet startTouchStartY = 0;\n\n\t\tlet lastMoveY = 0;\n\t\tlet startScrollTime = 0;\n\t\tlet scrollSpeed = 0;\n\t\tlet curScrollId = 0;\n\n\t\tthis.element.addEventListener(\"touchstart\", (evt) => {\n\t\t\tif (this.beginScrollHandler()) {\n\t\t\t\tthis.isUserScrolling = true;\n\n\t\t\t\tevt.preventDefault();\n\t\t\t\tstartScrollY = this.scrollOffset;\n\n\t\t\t\tstartTouchPosY = evt.touches[0].screenY;\n\t\t\t\tlastMoveY = startTouchPosY;\n\n\t\t\t\tstartTouchStartX = evt.touches[0].screenX;\n\t\t\t\tstartTouchStartY = evt.touches[0].screenY;\n\n\t\t\t\tstartScrollTime = Date.now();\n\t\t\t\tscrollSpeed = 0;\n\n\t\t\t\tthis.calcLayout(true, true);\n\t\t\t}\n\t\t});\n\n\t\tthis.element.addEventListener(\"touchmove\", (evt) => {\n\t\t\tif (this.beginScrollHandler()) {\n\t\t\t\tevt.preventDefault();\n\t\t\t\tconst currentY = evt.touches[0].screenY;\n\n\t\t\t\tconst deltaY = currentY - startTouchPosY;\n\t\t\t\tthis.scrollOffset = startScrollY - deltaY;\n\t\t\t\tthis.limitScrollOffset();\n\n\t\t\t\tconst now = Date.now();\n\t\t\t\tconst dt = now - startScrollTime;\n\t\t\t\tif (dt > 0) {\n\t\t\t\t\tscrollSpeed = (currentY - lastMoveY) / dt;\n\t\t\t\t}\n\t\t\t\tlastMoveY = currentY;\n\t\t\t\tstartScrollTime = now;\n\n\t\t\t\tthis.calcLayout(true, true);\n\t\t\t}\n\t\t});\n\n\t\tthis.element.addEventListener(\"touchend\", (evt) => {\n\t\t\tif (this.beginScrollHandler()) {\n\t\t\t\tevt.preventDefault();\n\n\t\t\t\tconst touch = evt.changedTouches[0];\n\t\t\t\tconst moveX = Math.abs(touch.screenX - startTouchStartX);\n\t\t\t\tconst moveY = Math.abs(touch.screenY - startTouchStartY);\n\n\t\t\t\tif (moveX < 10 && moveY < 10) {\n\t\t\t\t\tconst target = document.elementFromPoint(\n\t\t\t\t\t\ttouch.clientX,\n\t\t\t\t\t\ttouch.clientY,\n\t\t\t\t\t);\n\t\t\t\t\tif (target && this.element.contains(target)) {\n\t\t\t\t\t\t(target as HTMLElement).click();\n\t\t\t\t\t}\n\t\t\t\t\tthis.isUserScrolling = false;\n\t\t\t\t\tthis.endScrollHandler();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tstartTouchPosY = 0;\n\t\t\t\tconst scrollId = ++curScrollId;\n\n\t\t\t\tif (Math.abs(scrollSpeed) < 0.1) scrollSpeed = 0;\n\n\t\t\t\tlet lastFrameTime = performance.now();\n\n\t\t\t\tconst onScrollFrame = (time: number) => {\n\t\t\t\t\tif (scrollId !== curScrollId) return;\n\n\t\t\t\t\tconst dt = time - lastFrameTime;\n\t\t\t\t\tlastFrameTime = time;\n\n\t\t\t\t\tif (dt <= 0 || dt > 100) {\n\t\t\t\t\t\trequestAnimationFrame(onScrollFrame);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (Math.abs(scrollSpeed) > 0.05) {\n\t\t\t\t\t\tthis.scrollOffset -= scrollSpeed * dt;\n\n\t\t\t\t\t\tthis.limitScrollOffset();\n\n\t\t\t\t\t\tconst frictionFactor = 0.95 ** (dt / 16);\n\t\t\t\t\t\tscrollSpeed *= frictionFactor;\n\n\t\t\t\t\t\tthis.calcLayout(true, true);\n\n\t\t\t\t\t\trequestAnimationFrame(onScrollFrame);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.isUserScrolling = false;\n\t\t\t\t\t\tthis.endScrollHandler();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\trequestAnimationFrame(onScrollFrame);\n\t\t\t} else {\n\t\t\t\tthis.isUserScrolling = false;\n\t\t\t}\n\t\t});\n\n\t\tthis.element.addEventListener(\n\t\t\t\"wheel\",\n\t\t\t(evt) => {\n\t\t\t\tif (this.beginScrollHandler()) {\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t// this.isUserScrolling = true;\n\n\t\t\t\t\tif (evt.deltaMode === evt.DOM_DELTA_PIXEL) {\n\t\t\t\t\t\tthis.scrollOffset += evt.deltaY;\n\t\t\t\t\t\tthis.limitScrollOffset();\n\t\t\t\t\t\tthis.calcLayout(true, false);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.scrollOffset += evt.deltaY * 50;\n\t\t\t\t\t\tthis.limitScrollOffset();\n\t\t\t\t\t\tthis.calcLayout(false, false);\n\t\t\t\t\t}\n\n\t\t\t\t\t// if (this.wheelTimeout) {\n\t\t\t\t\t// \tclearTimeout(this.wheelTimeout);\n\t\t\t\t\t// }\n\n\t\t\t\t\t// this.wheelTimeout = setTimeout(() => {\n\t\t\t\t\t// \tthis.isUserScrolling = false;\n\t\t\t\t\t// \tthis.endScrollHandler();\n\t\t\t\t\t// }, 150);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ passive: false },\n\t\t);\n\t}\n\n\tprivate beginScrollHandler() {\n\t\tconst allowed = this.allowScroll;\n\t\tif (allowed) {\n\t\t\tthis.isScrolled = true;\n\t\t\tclearTimeout(this.scrolledHandler);\n\t\t\tthis.scrolledHandler = setTimeout(() => {\n\t\t\t\tthis.isScrolled = false;\n\t\t\t\tthis.scrollOffset = 0;\n\t\t\t}, 5000);\n\t\t}\n\t\treturn allowed;\n\t}\n\tprivate endScrollHandler() {}\n\tprivate limitScrollOffset() {\n\t\tthis.scrollOffset = Math.max(\n\t\t\tMath.min(this.scrollBoundary[1], this.scrollOffset),\n\t\t\tthis.scrollBoundary[0],\n\t\t);\n\t}\n\n\t/**\n\t * 设置文字动画的渐变宽度,单位以歌词行的主文字字体大小的倍数为单位,默认为 0.5,即一个全角字符的一半宽度\n\t *\n\t * 如果要模拟 Apple Music for Android 的效果,可以设置为 1\n\t *\n\t * 如果要模拟 Apple Music for iPad 的效果,可以设置为 0.5\n\t *\n\t * 如果想要近乎禁用渐变效果,可以设置成非常接近 0 的小数(例如 `0.0001` ),但是**不可以为 0**\n\t *\n\t * @param value 需要设置的渐变宽度,单位以歌词行的主文字字体大小的倍数为单位,默认为 0.5\n\t */\n\tsetWordFadeWidth(value = 0.5): void {\n\t\tthis.wordFadeWidth = Math.max(0.0001, value);\n\t}\n\n\t/**\n\t * 是否启用歌词行缩放效果,默认启用\n\t *\n\t * 如果启用,非选中的歌词行会轻微缩小以凸显当前播放歌词行效果\n\t *\n\t * 此效果对性能影响微乎其微,推荐启用\n\t * @param enable 是否启用歌词行缩放效果\n\t */\n\tsetEnableScale(enable = true): void {\n\t\tthis.enableScale = enable;\n\t\tthis.calcLayout();\n\t}\n\t/**\n\t * 获取当前是否启用了歌词行缩放效果\n\t * @returns 是否启用歌词行缩放效果\n\t */\n\tgetEnableScale(): boolean {\n\t\treturn this.enableScale;\n\t}\n\n\t/**\n\t * 获取当前文字动画的渐变宽度,单位以歌词行的主文字字体大小的倍数为单位\n\t * @returns 当前文字动画的渐变宽度,单位以歌词行的主文字字体大小的倍数为单位\n\t */\n\tgetWordFadeWidth(): number {\n\t\treturn this.wordFadeWidth;\n\t}\n\n\tsetIsSeeking(isSeeking: boolean): void {\n\t\tthis.isSeeking = isSeeking;\n\t}\n\t/**\n\t * 设置是否隐藏已经播放过的歌词行,默认不隐藏\n\t * @param hide 是否隐藏已经播放过的歌词行,默认不隐藏\n\t */\n\tsetHidePassedLines(hide: boolean): void {\n\t\tthis.hidePassedLines = hide;\n\t\tthis.calcLayout();\n\t}\n\t/**\n\t * 设置是否启用歌词行的模糊效果\n\t * @param enable 是否启用\n\t */\n\tsetEnableBlur(enable: boolean): void {\n\t\tif (this.enableBlur === enable) return;\n\t\tthis.enableBlur = enable;\n\t\tthis.calcLayout();\n\t}\n\n\t/**\n\t * 设置歌词中不雅用语的掩码模式\n\t * @param mode 掩码模式\n\t * @see {@link MaskObsceneWordsMode}\n\t */\n\tsetMaskObsceneWords(mode: MaskObsceneWordsMode): void {\n\t\tif (this.maskObsceneWords === mode) return;\n\t\tthis.maskObsceneWords = mode;\n\t\tthis.rebuildLyricLines();\n\t\tthis.calcLayout();\n\t}\n\n\t/**\n\t * 设置不雅用语掩码使用的字符,默认为 `*`\n\t * @param char 单个字符,用于替换不雅用语中的字符\n\t */\n\tsetMaskObsceneWordChar(char: string): void {\n\t\tconst c = char.charAt(0) || \"*\";\n\t\tif (this.maskObsceneWordChar === c) return;\n\t\tthis.maskObsceneWordChar = c;\n\t\tif (this.maskObsceneWords !== MaskObsceneWordsMode.Disabled) {\n\t\t\tthis.rebuildLyricLines();\n\t\t\tthis.calcLayout();\n\t\t}\n\t}\n\n\trebuildLyricLines(): void {\n\t\tfor (const lineObj of this.currentLyricLineObjects) {\n\t\t\tlineObj.rebuildElement();\n\t\t}\n\t}\n\t/**\n\t * 根据当前配置处理不雅用语单词\n\t * @param word 单词对象\n\t * @internal\n\t */\n\tprocessObsceneWord(word: LyricWord): string {\n\t\tconst text = word.word;\n\n\t\tif (\n\t\t\t!word.obscene ||\n\t\t\tthis.maskObsceneWords === MaskObsceneWordsMode.Disabled\n\t\t) {\n\t\t\treturn text;\n\t\t}\n\n\t\tconst maskChar = this.maskObsceneWordChar;\n\n\t\tif (this.maskObsceneWords === MaskObsceneWordsMode.FullMask) {\n\t\t\treturn text.replace(/\\S/g, maskChar);\n\t\t}\n\n\t\tif (this.maskObsceneWords === MaskObsceneWordsMode.PartialMask) {\n\t\t\tconst trimmed = text.trim();\n\n\t\t\tif (trimmed.length <= 2) {\n\t\t\t\treturn text.replace(/\\S/g, maskChar);\n\t\t\t}\n\n\t\t\tconst startPos = text.indexOf(trimmed);\n\t\t\tconst endPos = startPos + trimmed.length - 1;\n\n\t\t\treturn (\n\t\t\t\ttext.slice(0, startPos + 1) +\n\t\t\t\ttext.slice(startPos + 1, endPos).replace(/\\S/g, maskChar) +\n\t\t\t\ttext.slice(endPos)\n\t\t\t);\n\t\t}\n\n\t\treturn text;\n\t}\n\t/**\n\t * 设置目标歌词行的对齐方式,默认为 `center`\n\t *\n\t * - 设置成 `top` 的话将会向目标歌词行的顶部对齐\n\t * - 设置成 `bottom` 的话将会向目标歌词行的底部对齐\n\t * - 设置成 `center` 的话将会向目标歌词行的垂直中心对齐\n\t * @param alignAnchor 歌词行对齐方式,详情见函数说明\n\t */\n\tsetAlignAnchor(alignAnchor: \"top\" | \"bottom\" | \"center\"): void {\n\t\tthis.alignAnchor = alignAnchor;\n\t}\n\t/**\n\t * 设置默认的歌词行对齐位置,相对于整个歌词播放组件的大小位置,默认为 `0.5`\n\t * @param alignPosition 一个 `[0.0-1.0]` 之间的任意数字,代表组件高度由上到下的比例位置\n\t */\n\tsetAlignPosition(alignPosition: number): void {\n\t\tthis.alignPosition = alignPosition;\n\t}\n\n\t/**\n\t * 设置 overscan(视图上下额外缓冲渲染区)距离,单位:像素。\n\t * @param px 像素值,默认 300\n\t */\n\tsetOverscanPx(px: number): void {\n\t\tthis.overscanPx = Math.max(0, px | 0);\n\t}\n\t/** 获取当前 overscan 像素距离 */\n\tgetOverscanPx(): number {\n\t\treturn this.overscanPx;\n\t}\n\t/**\n\t * 设置是否使用物理弹簧算法实现歌词动画效果,默认启用\n\t *\n\t * 如果启用,则会通过弹簧算法实时处理歌词位置,但是需要性能足够强劲的电脑方可流畅运行\n\t *\n\t * 如果不启用,则会回退到基于 `transition` 的过渡效果,对低性能的机器比较友好,但是效果会比较单一\n\t */\n\tsetEnableSpring(enable = true): void {\n\t\tthis.disableSpring = !enable;\n\t\tif (enable) {\n\t\t\tthis.element.classList.remove(styles.disableSpring);\n\t\t} else {\n\t\t\tthis.element.classList.add(styles.disableSpring);\n\t\t}\n\t\tthis.calcLayout(true);\n\t}\n\t/**\n\t * 获取当前是否启用了物理弹簧\n\t * @returns 是否启用物理弹簧\n\t */\n\tgetEnableSpring(): boolean {\n\t\treturn !this.disableSpring;\n\t}\n\n\t/**\n\t * 获取当前播放时间里是否处于间奏区间\n\t * 如果是则会返回单位为毫秒的始末时间\n\t * 否则返回 undefined\n\t *\n\t * 这个只允许内部调用\n\t * @returns [开始时间,结束时间,大概处于的歌词行ID,下一句是否为对唱歌词] 或 undefined 如果不处于间奏区间\n\t */\n\tprotected getCurrentInterlude():\n\t\t| [number, number, number, boolean]\n\t\t| undefined {\n\t\tconst currentTime = this.currentTime + 20;\n\t\tconst currentIndex = this.scrollToIndex;\n\t\tconst lines = this.processedLines;\n\n\t\tconst checkGap = (\n\t\t\tk: number,\n\t\t): [number, number, number, boolean] | undefined => {\n\t\t\tif (k < -1 || k >= lines.length - 1) return undefined;\n\n\t\t\tconst prevLine = k === -1 ? null : lines[k];\n\t\t\tconst nextLine = lines[k + 1];\n\n\t\t\tconst gapStart = prevLine ? prevLine.endTime : 0;\n\t\t\tconst gapEnd = Math.max(gapStart, nextLine.startTime - 250);\n\n\t\t\tif (gapEnd - gapStart < 4000) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tif (gapEnd > currentTime && gapStart < currentTime) {\n\t\t\t\treturn [Math.max(gapStart, currentTime), gapEnd, k, nextLine.isDuet];\n\t\t\t}\n\t\t\treturn undefined;\n\t\t};\n\n\t\treturn (\n\t\t\tcheckGap(currentIndex - 1) ||\n\t\t\tcheckGap(currentIndex) ||\n\t\t\tcheckGap(currentIndex + 1)\n\t\t);\n\t}\n\n\t/**\n\t * 设置歌词的优化配置项,这些配置项默认全部开启\n\t *\n\t * 注意,如果在 `setLyricLines` 之后修改此配置,需要重新调用 `setLyricLines()` 才能对当前歌词生效\n\t * @param options 优化配置选项\n\t * @see {@link OptimizeLyricOptions}\n\t */\n\tsetOptimizeOptions(options: OptimizeLyricOptions): void {\n\t\tthis.optimizeOptions = { ...this.optimizeOptions, ...options };\n\t}\n\n\t/**\n\t * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误\n\t * @param lines 歌词数组\n\t * @param initialTime 初始时间,默认为 0\n\t */\n\tsetLyricLines(lines: LyricLine[], initialTime = 0): void {\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.log(\"设置歌词行\", lines, initialTime);\n\t\t}\n\n\t\tthis.initialLayoutFinished = true;\n\t\tthis.lastCurrentTime = initialTime;\n\t\tthis.currentTime = initialTime;\n\t\tthis.currentLyricLines = structuredClone(lines);\n\t\tthis.processedLines = structuredClone(this.currentLyricLines);\n\t\toptimizeLyricLines(this.processedLines, this.optimizeOptions);\n\n\t\tthis.isNonDynamic = true;\n\t\tfor (const line of this.processedLines) {\n\t\t\tif (line.words.length > 1) {\n\t\t\t\tthis.isNonDynamic = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis.hasDuetLine = this.processedLines.some((line) => line.isDuet);\n\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.dispose();\n\t\t}\n\n\t\tthis.interludeDots.setInterlude(undefined);\n\t\tthis.hotLines.clear();\n\t\tthis.bufferedLines.clear();\n\t\tthis.setCurrentTime(0, true);\n\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.log(\"歌词处理完成\", this);\n\t\t}\n\t}\n\n\t/**\n\t * 获取当前是否在播放\n\t * @returns 当前是否在播放\n\t */\n\tpublic getIsPlaying(): boolean {\n\t\treturn this.isPlaying;\n\t}\n\n\t/**\n\t * 设置当前播放进度,单位为毫秒且**必须是整数**,此时将会更新内部的歌词进度信息\n\t * 内部会根据调用间隔和播放进度自动决定如何滚动和显示歌词,所以这个的调用频率越快越准确越好\n\t *\n\t * 调用完成后,可以每帧调用 `update` 函数来执行歌词动画效果\n\t * @param time 当前播放进度,单位为毫秒\n\t */\n\tsetCurrentTime(time: number, isSeek = false): void {\n\t\t// 我在这里定义了歌词的选择状态:\n\t\t// 普通行:当前不处于时间范围内的歌词行\n\t\t// 热行:当前绝对处于播放时间内的歌词行,且一般会被立刻加入到缓冲行中\n\t\t// 缓冲行:一般处于播放时间后的歌词行,会因为当前播放状态的缘故推迟解除状态\n\n\t\t// 然后我们需要让歌词行为如下:\n\t\t// 如果当前仍有缓冲行的情况下加入新热行,则不会解除当前缓冲行,且也不会修改当前滚动位置\n\t\t// 如果当前所有缓冲行都将被删除且没有新热行加入,则删除所有缓冲行,且也不会修改当前滚动位置\n\t\t// 如果当前所有缓冲行都将被删除且有新热行加入,则删除所有缓冲行并加入新热行作为缓冲行,然后修改当前滚动位置\n\n\t\tthis.currentTime = time;\n\n\t\tif (!this.initialLayoutFinished && !isSeek) return;\n\n\t\tconst removedHotIds = new Set<number>();\n\t\tconst removedIds = new Set<number>();\n\t\tconst addedIds = new Set<number>();\n\n\t\t// 先检索当前已经超出时间范围的缓冲行,列入待删除集内\n\t\tfor (const lastHotId of this.hotLines) {\n\t\t\tconst line = this.processedLines[lastHotId];\n\t\t\tif (line) {\n\t\t\t\tif (line.isBG) continue;\n\t\t\t\tconst nextLine = this.processedLines[lastHotId + 1];\n\t\t\t\tif (nextLine?.isBG) {\n\t\t\t\t\tconst nextMainLine = this.processedLines[lastHotId + 2];\n\t\t\t\t\tconst startTime = Math.min(line.startTime, nextLine?.startTime);\n\t\t\t\t\tconst endTime = Math.min(\n\t\t\t\t\t\tMath.max(line.endTime, nextMainLine?.startTime ?? Number.MAX_VALUE),\n\t\t\t\t\t\tMath.max(line.endTime, nextLine?.endTime),\n\t\t\t\t\t);\n\t\t\t\t\tif (startTime > time || endTime <= time) {\n\t\t\t\t\t\tthis.hotLines.delete(lastHotId);\n\t\t\t\t\t\tremovedHotIds.add(lastHotId);\n\t\t\t\t\t\tthis.hotLines.delete(lastHotId + 1);\n\t\t\t\t\t\tremovedHotIds.add(lastHotId + 1);\n\t\t\t\t\t\tif (isSeek) {\n\t\t\t\t\t\t\tthis.currentLyricLineObjects[lastHotId]?.disable();\n\t\t\t\t\t\t\tthis.currentLyricLineObjects[lastHotId + 1]?.disable();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (line.startTime > time || line.endTime <= time) {\n\t\t\t\t\tthis.hotLines.delete(lastHotId);\n\t\t\t\t\tremovedHotIds.add(lastHotId);\n\t\t\t\t\tif (isSeek) this.currentLyricLineObjects[lastHotId]?.disable();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.hotLines.delete(lastHotId);\n\t\t\t\tremovedHotIds.add(lastHotId);\n\t\t\t\tif (isSeek) this.currentLyricLineObjects[lastHotId]?.disable();\n\t\t\t}\n\t\t}\n\t\tthis.currentLyricLineObjects.forEach((lineObj, id, arr) => {\n\t\t\tconst line = lineObj.getLine();\n\n\t\t\tif (!line.isBG && line.startTime <= time && line.endTime > time) {\n\t\t\t\tif (isSeek) {\n\t\t\t\t\tlineObj.enable(time, this.isPlaying);\n\t\t\t\t}\n\n\t\t\t\tif (!this.hotLines.has(id)) {\n\t\t\t\t\tthis.hotLines.add(id);\n\t\t\t\t\taddedIds.add(id);\n\n\t\t\t\t\tif (!isSeek) {\n\t\t\t\t\t\tlineObj.enable();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (arr[id + 1]?.getLine()?.isBG) {\n\t\t\t\t\t\tthis.hotLines.add(id + 1);\n\t\t\t\t\t\taddedIds.add(id + 1);\n\t\t\t\t\t\tif (isSeek) {\n\t\t\t\t\t\t\tarr[id + 1].enable(time, this.isPlaying);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tarr[id + 1].enable();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tfor (const v of this.bufferedLines) {\n\t\t\tif (!this.hotLines.has(v)) {\n\t\t\t\tremovedIds.add(v);\n\t\t\t\tif (isSeek) this.currentLyricLineObjects[v]?.disable();\n\t\t\t}\n\t\t}\n\t\tif (isSeek) {\n\t\t\tthis.bufferedLines.clear();\n\t\t\tfor (const v of this.hotLines) {\n\t\t\t\tthis.bufferedLines.add(v);\n\t\t\t}\n\n\t\t\tif (this.bufferedLines.size > 0) {\n\t\t\t\tthis.scrollToIndex = Math.min(...this.bufferedLines);\n\t\t\t} else {\n\t\t\t\tconst foundIndex = this.processedLines.findIndex(\n\t\t\t\t\t(line) => line.startTime >= time,\n\t\t\t\t);\n\n\t\t\t\tthis.scrollToIndex =\n\t\t\t\t\tfoundIndex === -1 ? this.processedLines.length : foundIndex;\n\t\t\t}\n\n\t\t\tthis.resetScroll();\n\t\t\tthis.calcLayout();\n\t\t} else if (removedIds.size > 0 || addedIds.size > 0) {\n\t\t\tif (removedIds.size === 0 && addedIds.size > 0) {\n\t\t\t\tfor (const v of addedIds) {\n\t\t\t\t\tthis.bufferedLines.add(v);\n\t\t\t\t\tthis.currentLyricLineObjects[v]?.enable();\n\t\t\t\t}\n\t\t\t\tthis.scrollToIndex = Math.min(...this.bufferedLines);\n\t\t\t\tthis.calcLayout();\n\t\t\t} else if (addedIds.size === 0 && removedIds.size > 0) {\n\t\t\t\tif (eqSet(removedIds, this.bufferedLines)) {\n\t\t\t\t\tfor (const v of this.bufferedLines) {\n\t\t\t\t\t\tif (!this.hotLines.has(v)) {\n\t\t\t\t\t\t\tthis.bufferedLines.delete(v);\n\t\t\t\t\t\t\tthis.currentLyricLineObjects[v]?.disable();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.calcLayout();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const v of addedIds) {\n\t\t\t\t\tthis.bufferedLines.add(v);\n\t\t\t\t\tthis.currentLyricLineObjects[v]?.enable();\n\t\t\t\t}\n\t\t\t\tfor (const v of removedIds) {\n\t\t\t\t\tthis.bufferedLines.delete(v);\n\t\t\t\t\tthis.currentLyricLineObjects[v]?.disable();\n\t\t\t\t}\n\t\t\t\tif (this.bufferedLines.size > 0)\n\t\t\t\t\tthis.scrollToIndex = Math.min(...this.bufferedLines);\n\t\t\t\tthis.calcLayout();\n\t\t\t}\n\t\t}\n\n\t\tif (this.bufferedLines.size === 0 && this.processedLines.length > 0) {\n\t\t\tconst lastLine = this.processedLines[this.processedLines.length - 1];\n\n\t\t\tconst bottomEl = this.bottomLine.getElement();\n\t\t\tconst hasBottomContent = bottomEl.innerHTML.trim().length > 0;\n\n\t\t\tif (time >= lastLine.endTime) {\n\t\t\t\tconst targetIndex = hasBottomContent\n\t\t\t\t\t? this.processedLines.length\n\t\t\t\t\t: this.processedLines.length - 1;\n\n\t\t\t\tif (this.scrollToIndex !== targetIndex) {\n\t\t\t\t\tthis.scrollToIndex = targetIndex;\n\t\t\t\t\tthis.calcLayout();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.lastCurrentTime = time;\n\t}\n\n\tprotected updateDynamicSpringParams(): void {\n\t\tif (!this.getEnableSpring() || this.processedLines.length === 0) return;\n\n\t\tconst currentIndex = this.scrollToIndex;\n\t\tconst currentLine = this.processedLines[currentIndex];\n\t\tconst prevLine = this.processedLines[currentIndex - 1];\n\n\t\tif (currentLine && prevLine) {\n\t\t\tconst interval =\n\t\t\t\tcurrentLine.startTime -\n\t\t\t\t(prevLine?.words[0]?.startTime ?? prevLine.startTime);\n\n\t\t\tconst MIN_INTERVAL = 100;\n\t\t\tconst MAX_INTERVAL = 800;\n\t\t\tconst clampedInterval = Math.max(\n\t\t\t\tMIN_INTERVAL,\n\t\t\t\tMath.min(MAX_INTERVAL, interval),\n\t\t\t);\n\n\t\t\tconst MAX_STIFFNESS = 220;\n\t\t\tconst MIN_STIFFNESS = 170;\n\n\t\t\tlet ratio =\n\t\t\t\t1 - (clampedInterval - MIN_INTERVAL) / (MAX_INTERVAL - MIN_INTERVAL);\n\n\t\t\tratio = ratio ** 0.2;\n\n\t\t\tconst targetStiffness =\n\t\t\t\tMIN_STIFFNESS + ratio * (MAX_STIFFNESS - MIN_STIFFNESS);\n\n\t\t\tconst dampingMultiplier = 2.2;\n\t\t\tconst targetDamping = Math.sqrt(targetStiffness) * dampingMultiplier;\n\n\t\t\tthis.setLinePosYSpringParams({\n\t\t\t\tstiffness: targetStiffness,\n\t\t\t\tdamping: targetDamping,\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * 重新布局定位歌词行的位置,调用完成后再逐帧调用 `update`\n\t * 函数即可让歌词通过动画移动到目标位置。\n\t *\n\t * 函数有一个 `force` 参数,用于指定是否强制修改布局,也就是不经过动画直接调整元素位置和大小。\n\t *\n\t * 此函数还有一个 `reflow` 参数,用于指定是否需要重新计算布局\n\t *\n\t * 因为计算布局必定会导致浏览器重排布局,所以会大幅度影响流畅度和性能,故请只在以下情况下将其设置为 true:\n\t *\n\t * 1. 歌词页面大小发生改变时(这个组件会自行处理)\n\t * 2. 加载了新的歌词时(不论前后歌词是否完全一样)\n\t * 3. 用户自行跳转了歌曲播放位置(不论距离远近)\n\t *\n\t * @param sync 是否同步执行,通常用于初始化或 Resize 时立即布局\n\t * @param force 是否绕过弹簧效果强制更新位置\n\t */\n\tasync calcLayout(sync = false, force = false): Promise<void> {\n\t\tconst interlude = this.getCurrentInterlude();\n\t\tconst isInterludeActive = !!interlude;\n\n\t\tif (\n\t\t\tthis.targetAlignIndex !== this.scrollToIndex ||\n\t\t\tthis.lastInterludeState !== isInterludeActive\n\t\t) {\n\t\t\tthis.lastInterludeState = isInterludeActive;\n\n\t\t\tif (this.isSeeking) {\n\t\t\t\tthis.setLinePosYSpringParams({ stiffness: 90, damping: 15 });\n\t\t\t} else if (isInterludeActive) {\n\t\t\t\tthis.setLinePosYSpringParams({ stiffness: 90, damping: 15 });\n\t\t\t} else {\n\t\t\t\tthis.updateDynamicSpringParams();\n\t\t\t}\n\t\t}\n\n\t\tlet curPos = -this.scrollOffset;\n\t\tconst targetAlignIndex = this.scrollToIndex;\n\t\tlet isNextDuet = false;\n\t\tif (interlude) {\n\t\t\tisNextDuet = interlude[3];\n\t\t} else {\n\t\t\tthis.interludeDots.setInterlude(undefined);\n\t\t}\n\n\t\tconst fontSize = this.baseFontSize || 24;\n\t\tconst dotMargin = fontSize * 0.4;\n\t\tconst totalInterludeHeight = this.interludeDotsSize[1] + dotMargin * 2;\n\n\t\tif (interlude) {\n\t\t\tif (interlude[2] !== -1) {\n\t\t\t\tcurPos -= totalInterludeHeight;\n\t\t\t}\n\t\t}\n\t\t// 避免一开始就让所有歌词行挤在一起\n\t\tconst LINE_HEIGHT_FALLBACK = this.size[1] / 5;\n\t\tconst scrollOffset = this.currentLyricLineObjects\n\t\t\t.slice(0, targetAlignIndex)\n\t\t\t.reduce(\n\t\t\t\t(acc, el) =>\n\t\t\t\t\tacc +\n\t\t\t\t\t(el.getLine().isBG && this.isPlaying\n\t\t\t\t\t\t? 0\n\t\t\t\t\t\t: (this.lyricLinesSize.get(el)?.[1] ?? LINE_HEIGHT_FALLBACK)),\n\t\t\t\t0,\n\t\t\t);\n\t\tthis.scrollBoundary[0] = -scrollOffset;\n\t\tcurPos -= scrollOffset;\n\t\tcurPos += this.size[1] * this.alignPosition;\n\t\tconst curLine = this.currentLyricLineObjects[targetAlignIndex];\n\t\tthis.targetAlignIndex = targetAlignIndex;\n\n\t\tconst isBottomFocused =\n\t\t\ttargetAlignIndex === this.currentLyricLineObjects.length;\n\t\tthis.bottomLine.setFocused(isBottomFocused);\n\n\t\tlet targetLineHeight = 0;\n\t\tif (curLine) {\n\t\t\ttargetLineHeight =\n\t\t\t\tthis.lyricLinesSize.get(curLine)?.[1] ?? LINE_HEIGHT_FALLBACK;\n\t\t} else if (isBottomFocused) {\n\t\t\ttargetLineHeight = this.bottomLine.lineSize[1];\n\t\t}\n\n\t\tif (targetLineHeight > 0) {\n\t\t\tswitch (this.alignAnchor) {\n\t\t\t\tcase \"bottom\":\n\t\t\t\t\tcurPos -= targetLineHeight;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"center\":\n\t\t\t\t\tcurPos -= targetLineHeight / 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"top\":\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst latestIndex = Math.max(...this.bufferedLines);\n\t\tlet delay = 0;\n\t\tlet baseDelay = sync ? 0 : 0.05;\n\t\tlet setDots = false;\n\t\tthis.currentLyricLineObjects.forEach((lineObj, i) => {\n\t\t\tconst hasBuffered = this.bufferedLines.has(i);\n\t\t\tconst isActive =\n\t\t\t\thasBuffered || (i >= this.scrollToIndex && i < latestIndex);\n\t\t\tconst line = lineObj.getLine();\n\n\t\t\tconst shouldShowDots = interlude && i === interlude[2] + 1;\n\n\t\t\tif (!setDots && shouldShowDots) {\n\t\t\t\tsetDots = true;\n\n\t\t\t\tcurPos += dotMargin;\n\n\t\t\t\tlet targetX = 0;\n\t\t\t\tif (interlude && isNextDuet) {\n\t\t\t\t\ttargetX = this.size[0] - this.interludeDotsSize[0];\n\t\t\t\t}\n\n\t\t\t\tthis.interludeDots.setTransform(targetX, curPos);\n\n\t\t\t\tif (interlude) {\n\t\t\t\t\tthis.interludeDots.setInterlude([interlude[0], interlude[1]]);\n\t\t\t\t}\n\t\t\t\tcurPos += this.interludeDotsSize[1];\n\t\t\t\tcurPos += dotMargin;\n\t\t\t}\n\n\t\t\tlet targetOpacity: number;\n\n\t\t\tif (this.hidePassedLines) {\n\t\t\t\tif (\n\t\t\t\t\ti < (interlude ? interlude[2] + 1 : this.scrollToIndex) &&\n\t\t\t\t\tthis.isPlaying\n\t\t\t\t) {\n\t\t\t\t\t// 为了避免浏览器优化,这里使用了一个极小但不为零的值(几乎不可见)\n\t\t\t\t\ttargetOpacity = 0.00001;\n\t\t\t\t} else if (hasBuffered) {\n\t\t\t\t\ttargetOpacity = 0.85;\n\t\t\t\t} else {\n\t\t\t\t\ttargetOpacity = this.isNonDynamic ? 0.2 : 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (hasBuffered) {\n\t\t\t\t\ttargetOpacity = 0.85;\n\t\t\t\t} else {\n\t\t\t\t\ttargetOpacity = this.isNonDynamic ? 0.2 : 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst blurLevel = this.calculateBlur(i, isActive, latestIndex);\n\n\t\t\tconst SCALE_ASPECT = this.enableScale ? 97 : 100;\n\t\t\tlet targetScale = 100;\n\n\t\t\tif (!isActive && this.isPlaying) {\n\t\t\t\tif (line.isBG) {\n\t\t\t\t\ttargetScale = 75;\n\t\t\t\t} else {\n\t\t\t\t\ttargetScale = SCALE_ASPECT;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst renderMode = isActive\n\t\t\t\t? LyricLineRenderMode.GRADIENT\n\t\t\t\t: LyricLineRenderMode.SOLID;\n\n\t\t\tlineObj.setTransform(\n\t\t\t\tcurPos,\n\t\t\t\ttargetScale,\n\t\t\t\ttargetOpacity,\n\t\t\t\tblurLevel,\n\t\t\t\tforce,\n\t\t\t\tdelay,\n\t\t\t\trenderMode,\n\t\t\t);\n\n\t\t\tif (line.isBG && (isActive || !this.isPlaying)) {\n\t\t\t\tcurPos += this.lyricLinesSize.get(lineObj)?.[1] ?? LINE_HEIGHT_FALLBACK;\n\t\t\t} else if (!line.isBG) {\n\t\t\t\tcurPos += this.lyricLinesSize.get(lineObj)?.[1] ?? LINE_HEIGHT_FALLBACK;\n\t\t\t}\n\t\t\tif (curPos >= 0 && !this.isSeeking) {\n\t\t\t\tif (!line.isBG) delay += baseDelay;\n\n\t\t\t\tif (i >= this.scrollToIndex) baseDelay /= 1.05;\n\t\t\t}\n\t\t});\n\t\tthis.scrollBoundary[1] = curPos + this.scrollOffset - this.size[1] / 2;\n\n\t\tconst bottomIndex = this.currentLyricLineObjects.length;\n\t\tconst finalBottomBlur = this.calculateBlur(\n\t\t\tbottomIndex,\n\t\t\tisBottomFocused,\n\t\t\tlatestIndex,\n\t\t);\n\n\t\tthis.bottomLine.setTransform(0, curPos, finalBottomBlur, force, delay);\n\t}\n\n\tprotected calculateBlur(\n\t\titemIndex: number,\n\t\tisActive: boolean,\n\t\tlatestIndex: number,\n\t): number {\n\t\tif (!this.enableBlur || this.isUserScrolling || isActive) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet blurLevel = 1;\n\n\t\tif (itemIndex < this.scrollToIndex) {\n\t\t\tblurLevel += Math.abs(this.scrollToIndex - itemIndex) + 1;\n\t\t} else {\n\t\t\tblurLevel += Math.abs(\n\t\t\t\titemIndex - Math.max(this.scrollToIndex, latestIndex),\n\t\t\t);\n\t\t}\n\n\t\treturn window.innerWidth <= 1024 ? blurLevel * 0.8 : blurLevel;\n\t}\n\n\t/**\n\t * 设置所有歌词行在横坐标上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t * @deprecated 考虑到横向弹簧效果并不常见,所以这个函数将会在未来的版本中移除\n\t */\n\tsetLinePosXSpringParams(_params: Partial<SpringParams> = {}): void {}\n\t/**\n\t * 设置所有歌词行在纵坐标上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tsetLinePosYSpringParams(params: Partial<SpringParams> = {}): void {\n\t\tthis.posYSpringParams = {\n\t\t\t...this.posYSpringParams,\n\t\t\t...params,\n\t\t};\n\t\tthis.bottomLine.lineTransforms.posY.updateParams(this.posYSpringParams);\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.lineTransforms.posY.updateParams(this.posYSpringParams);\n\t\t}\n\t}\n\t/**\n\t * 设置所有歌词行在缩放大小上的弹簧属性,包括重量、弹力和阻力。\n\t *\n\t * @param params 需要设置的弹簧属性,提供的属性将会覆盖原来的属性,未提供的属性将会保持原样\n\t */\n\tsetLineScaleSpringParams(params: Partial<SpringParams> = {}): void {\n\t\tthis.scaleSpringParams = {\n\t\t\t...this.scaleSpringParams,\n\t\t\t...params,\n\t\t};\n\t\tthis.scaleForBGSpringParams = {\n\t\t\t...this.scaleForBGSpringParams,\n\t\t\t...params,\n\t\t};\n\t\tfor (const lineObj of this.currentLyricLineObjects) {\n\t\t\tif (lineObj.getLine().isBG) {\n\t\t\t\tlineObj.lineTransforms.scale.updateParams(this.scaleForBGSpringParams);\n\t\t\t} else {\n\t\t\t\tlineObj.lineTransforms.scale.updateParams(this.scaleSpringParams);\n\t\t\t}\n\t\t}\n\t}\n\tprotected isPlaying = true;\n\t/**\n\t * 暂停部分效果演出,目前会暂停播放间奏点的动画,且将背景歌词显示出来\n\t */\n\tpause(): void {\n\t\tthis.interludeDots.pause();\n\t\tif (this.isPlaying) {\n\t\t\tthis.isPlaying = false;\n\t\t\tthis.calcLayout();\n\t\t}\n\t}\n\t/**\n\t * 恢复部分效果演出,目前会恢复播放间奏点的动画\n\t */\n\tresume(): void {\n\t\tthis.interludeDots.resume();\n\t\tif (!this.isPlaying) {\n\t\t\tthis.isPlaying = true;\n\t\t\tthis.calcLayout();\n\t\t}\n\t}\n\t/**\n\t * 更新动画,这个函数应该被逐帧调用或者在以下情况下调用一次:\n\t *\n\t * 1. 刚刚调用完设置歌词函数的时候\n\t * @param delta 距离上一次被调用到现在的时长,单位为毫秒(可为浮点数)\n\t */\n\n\tupdate(delta = 0): void {\n\t\tthis.bottomLine.update(delta / 1000);\n\t\tthis.interludeDots.update(delta);\n\t}\n\n\tprotected onResize(): void {}\n\n\t/**\n\t * 获取一个特殊的底栏元素,默认是空白的,可以往内部添加任意元素\n\t *\n\t * 这个元素始终在歌词的底部,可以用于显示歌曲创作者等信息\n\t *\n\t * 但是请勿删除该元素,只能在内部存放元素\n\t *\n\t * @returns 一个元素,可以往内部添加任意元素\n\t */\n\tgetBottomLineElement(): HTMLElement {\n\t\treturn this.bottomLine.getElement();\n\t}\n\t/**\n\t * 重置用户滚动状态\n\t *\n\t * 请在用户完成滚动点击跳转歌词时调用本事件再调用 `calcLayout` 以正确滚动到目标位置\n\t */\n\tresetScroll(): void {\n\t\tthis.isScrolled = false;\n\t\tthis.scrollOffset = 0;\n\t\tclearTimeout(this.scrolledHandler);\n\t}\n\t/**\n\t * 获取当前歌词数组\n\t *\n\t * 一般和最后调用 `setLyricLines` 给予的参数一样\n\t * @returns 当前歌词数组\n\t */\n\tgetLyricLines(): LyricLine[] {\n\t\treturn this.currentLyricLines;\n\t}\n\t/**\n\t * 获取当前歌词的播放位置\n\t *\n\t * 一般和最后调用 `setCurrentTime` 给予的参数一样\n\t * @returns 当前播放位置\n\t */\n\tgetCurrentTime(): number {\n\t\treturn this.currentTime;\n\t}\n\n\tgetElement(): HTMLElement {\n\t\treturn this.element;\n\t}\n\tdispose(): void {\n\t\tthis.element.remove();\n\t\twindow.removeEventListener(\"pageshow\", this.onPageShow);\n\t\twindow.removeEventListener(\"pagehide\", this.onPageHide);\n\t}\n}\n\ninterface LineTransforms {\n\tposY: Spring;\n\tscale: Spring;\n}\n\n/**\n * 所有标准歌词行的基类\n * @internal\n */\nexport abstract class LyricLineBase extends EventTarget implements Disposable {\n\tprotected top = 0;\n\tprotected scale = 1;\n\tprotected blur = 0;\n\tprotected opacity = 1;\n\tprotected delay = 0;\n\treadonly lineTransforms: LineTransforms = {\n\t\tposY: new Spring(0),\n\t\tscale: new Spring(100),\n\t};\n\tabstract getLine(): LyricLine;\n\tabstract enable(time?: number, shouldPlay?: boolean): void;\n\tabstract disable(): void;\n\tabstract resume(): void;\n\tabstract pause(): void;\n\tonLineSizeChange(_size: [number, number]): void {}\n\tsetTransform(\n\t\ttop: number = this.top,\n\t\tscale: number = this.scale,\n\t\topacity: number = this.opacity,\n\t\tblur: number = this.blur,\n\t\t_force = false,\n\t\tdelay = 0,\n\t\t_mode: LyricLineRenderMode = LyricLineRenderMode.SOLID,\n\t): void {\n\t\tthis.top = top;\n\t\tthis.scale = scale;\n\t\tthis.opacity = opacity;\n\t\tthis.blur = blur;\n\t\tthis.delay = delay;\n\t}\n\n\trebuildElement(): void {}\n\n\t/**\n\t * 判定歌词是否可以应用强调辉光效果\n\t *\n\t * 果子在对辉光效果的解释是一种强调(emphasized)效果\n\t *\n\t * 条件是一个单词时长大于等于 1s 且长度小于等于 7\n\t *\n\t * @param word 单词\n\t * @returns 是否可以应用强调辉光效果\n\t */\n\tstatic shouldEmphasize(word: LyricWord): boolean {\n\t\tif (isCJK(word.word)) return word.endTime - word.startTime >= 1000;\n\n\t\treturn (\n\t\t\tword.endTime - word.startTime >= 1000 &&\n\t\t\tword.word.trim().length <= 7 &&\n\t\t\tword.word.trim().length > 1\n\t\t);\n\t}\n\tabstract update(delta?: number): void;\n\tdispose(): void {}\n}\n","import type { LyricWord } from \"../interfaces.ts\";\nimport { isCJK } from \"./is-cjk.ts\";\n\nconst hasSegmenter =\n\ttypeof Intl !== \"undefined\" && typeof Intl.Segmenter !== \"undefined\";\n\n/**\n * 将输入的单词重新分组,之间没有空格的单词将会组合成一个单词数组\n *\n * 例如输入:`[\"Life\", \" \", \"is\", \" a\", \" su\", \"gar so\", \"sweet\"]`\n *\n * 应该返回:`[\"Life\", \" \", \"is\", \" a\", [\" su\", \"gar\"], \"so\", \"sweet\"]`\n * @param words 输入的单词数组\n * @returns 重新分组后的单词数组\n */\nexport function chunkAndSplitLyricWords(\n\twords: LyricWord[],\n): (LyricWord | LyricWord[])[] {\n\tconst atoms: LyricWord[] = [];\n\n\tfor (const w of words) {\n\t\tconst content = w.word.trim();\n\t\tconst isSpace = content.length === 0;\n\t\tconst romanWord = w.romanWord ?? \"\";\n\t\tconst obscene = w.obscene ?? false;\n\t\tconst hasRuby = (w.ruby?.length ?? 0) > 0;\n\n\t\tif (isSpace) {\n\t\t\tatoms.push({ ...w });\n\t\t\tcontinue;\n\t\t}\n\t\tif (hasRuby) {\n\t\t\tatoms.push({ ...w });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parts = w.word.split(/(\\s+)/).filter((p) => p.length > 0);\n\n\t\tlet currentOffset = 0;\n\t\tconst totalLength = w.word.replace(/\\s/g, \"\").length || 1;\n\n\t\tfor (const part of parts) {\n\t\t\tif (!part.trim()) {\n\t\t\t\tconst startTime =\n\t\t\t\t\tw.startTime +\n\t\t\t\t\t(currentOffset / totalLength) * (w.endTime - w.startTime);\n\n\t\t\t\tatoms.push({\n\t\t\t\t\tword: part,\n\t\t\t\t\tromanWord: \"\",\n\t\t\t\t\tstartTime: startTime,\n\t\t\t\t\tendTime: startTime,\n\t\t\t\t\tobscene: obscene,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isCJK(part) && part.length > 1 && romanWord.trim().length === 0) {\n\t\t\t\tconst chars = part.split(\"\");\n\t\t\t\tfor (const char of chars) {\n\t\t\t\t\tconst charDuration = (1 / totalLength) * (w.endTime - w.startTime);\n\t\t\t\t\tconst startTime =\n\t\t\t\t\t\tw.startTime +\n\t\t\t\t\t\t(currentOffset / totalLength) * (w.endTime - w.startTime);\n\t\t\t\t\tatoms.push({\n\t\t\t\t\t\tword: char,\n\t\t\t\t\t\tromanWord: \"\",\n\t\t\t\t\t\tstartTime: startTime,\n\t\t\t\t\t\tendTime: startTime + charDuration,\n\t\t\t\t\t\tobscene: obscene,\n\t\t\t\t\t});\n\t\t\t\t\tcurrentOffset += 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst partRealLen = part.length;\n\t\t\t\tconst duration =\n\t\t\t\t\t(partRealLen / totalLength) * (w.endTime - w.startTime);\n\t\t\t\tconst startTime =\n\t\t\t\t\tw.startTime +\n\t\t\t\t\t(currentOffset / totalLength) * (w.endTime - w.startTime);\n\n\t\t\t\tatoms.push({\n\t\t\t\t\tword: part,\n\t\t\t\t\tromanWord: romanWord,\n\t\t\t\t\tstartTime: startTime,\n\t\t\t\t\tendTime: startTime + duration,\n\t\t\t\t\tobscene: obscene,\n\t\t\t\t});\n\t\t\t\tcurrentOffset += partRealLen;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!hasSegmenter) {\n\t\treturn atoms;\n\t}\n\n\tconst fullText = atoms.map((a) => a.word).join(\"\");\n\tconst segmenter = new Intl.Segmenter(undefined, { granularity: \"word\" });\n\tconst segments = Array.from(segmenter.segment(fullText));\n\n\tconst result: (LyricWord | LyricWord[])[] = [];\n\tlet atomIndex = 0;\n\tlet expectedLength = 0;\n\tlet actualLength = 0;\n\tlet currentGroup: LyricWord[] = [];\n\n\tfor (const segment of segments) {\n\t\tconst segmentLen = segment.segment.length;\n\t\texpectedLength += segmentLen;\n\n\t\twhile (actualLength < expectedLength && atomIndex < atoms.length) {\n\t\t\tconst currentAtom = atoms[atomIndex];\n\t\t\tcurrentGroup.push(currentAtom);\n\t\t\tactualLength += currentAtom.word.length;\n\t\t\tatomIndex++;\n\t\t}\n\n\t\tif (actualLength === expectedLength) {\n\t\t\twhile (currentGroup.length > 1 && !currentGroup[0].word.trim()) {\n\t\t\t\tconst spaceAtom = currentGroup.shift();\n\t\t\t\tif (spaceAtom) {\n\t\t\t\t\tresult.push(spaceAtom);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentGroup.length === 1) {\n\t\t\t\tresult.push(currentGroup[0]);\n\t\t\t} else if (currentGroup.length > 1) {\n\t\t\t\tresult.push(currentGroup);\n\t\t\t}\n\t\t\tcurrentGroup = [];\n\t\t}\n\t}\n\n\twhile (atomIndex < atoms.length) {\n\t\tresult.push(atoms[atomIndex++]);\n\t}\n\n\tif (currentGroup.length > 0) {\n\t\tif (currentGroup.length === 1) {\n\t\t\tresult.push(currentGroup[0]);\n\t\t} else {\n\t\t\tresult.push(currentGroup);\n\t\t}\n\t}\n\n\treturn result;\n}\n","// biome-ignore format: matrix\nexport type Matrix4 = [\n\tnumber, number, number, number,\n\tnumber, number, number, number,\n\tnumber, number, number, number,\n\tnumber, number, number, number,\n];\n\nexport function createMatrix4(): Matrix4 {\n\t// biome-ignore format: matrix\n\treturn [\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0,\n 0, 0, 0, 1\n ];\n}\n\nexport function scaleMatrix4(\n\tm: Matrix4,\n\tscale = 1,\n\torigin = { x: 0, y: 0 },\n): Matrix4 {\n\tconst [ox, oy] = [origin.x, origin.y];\n\t// biome-ignore format: matrix\n\treturn [\n m[0] * scale , m[1] * scale , m[2] * scale , m[3],\n m[4] * scale , m[5] * scale , m[6] * scale , m[7],\n m[8] * scale , m[9] * scale , m[10] * scale, m[11],\n m[12] - ox * scale + ox, m[13] - oy * scale + oy, m[14] , m[15]\n ];\n}\n\nexport function translateMatrix4(m: Matrix4, x = 0, y = 0, z = 0): Matrix4 {\n\t// biome-ignore format: matrix\n\treturn [\n m[0] , m[1] , m[2] , m[3] ,\n m[4] , m[5] , m[6] , m[7] ,\n m[8] , m[9] , m[10] , m[11],\n m[12] + x, m[13] + y, m[14] + z, m[15]\n ];\n}\n\nexport function matrix4ToCSS(m: Matrix4, fractionDigits = 4): string {\n\tconst format = (n: number, _: number) => n.toFixed(fractionDigits);\n\treturn `matrix3d(${m.map(format).join(\", \")})`;\n}\n","import bezier from \"bezier-easing\";\nimport type { LyricLine, LyricWord } from \"../../interfaces.ts\";\nimport styles from \"../../styles/lyric-player.module.css\";\nimport { isCJK } from \"../../utils/is-cjk.ts\";\nimport { chunkAndSplitLyricWords } from \"../../utils/lyric-split-words.ts\";\nimport {\n\tcreateMatrix4,\n\tmatrix4ToCSS,\n\tscaleMatrix4,\n} from \"../../utils/matrix.ts\";\nimport { LyricLineBase } from \"../base.ts\";\nimport { LyricLineRenderMode } from \"../index.ts\";\nimport type { DomLyricPlayer } from \".\";\n\ninterface RealWord extends LyricWord {\n\tmainElement: HTMLSpanElement;\n\tsubElements: HTMLSpanElement[];\n\telementAnimations: Animation[];\n\tmaskAnimations: Animation[];\n\twidth: number;\n\theight: number;\n\tpadding: number;\n\tshouldEmphasize: boolean;\n}\n\nconst ANIMATION_FRAME_QUANTITY = 32;\n\nconst norNum = (min: number, max: number) => (x: number) =>\n\tMath.min(1, Math.max(0, (x - min) / (max - min)));\nconst EMP_EASING_MID = 0.5;\nconst beginNum = norNum(0, EMP_EASING_MID);\nconst endNum = norNum(EMP_EASING_MID, 1);\n\nconst bezIn = bezier(0.2, 0.4, 0.58, 1.0);\nconst bezOut = bezier(0.3, 0.0, 0.58, 1.0);\n\nconst makeEmpEasing = (mid: number) => {\n\treturn (x: number) => (x < mid ? bezIn(beginNum(x)) : 1 - bezOut(endNum(x)));\n};\n\nfunction generateFadeGradient(\n\twidth: number,\n\tpadding = 0,\n\tbright = \"rgba(0,0,0,var(--bright-mask-alpha, 1.0))\",\n\tdark = \"rgba(0,0,0,var(--dark-mask-alpha, 1.0))\",\n): [string, number] {\n\tconst totalAspect = 2 + width + padding;\n\tconst widthInTotal = width / totalAspect;\n\tconst leftPos = (1 - widthInTotal) / 2;\n\treturn [\n\t\t`linear-gradient(to right,${bright} ${leftPos * 100}%,${dark} ${\n\t\t\t(leftPos + widthInTotal) * 100\n\t\t}%)`,\n\t\ttotalAspect,\n\t];\n}\n\nexport class RawLyricLineMouseEvent extends MouseEvent {\n\tconstructor(\n\t\tpublic readonly line: LyricLineBase,\n\t\tevent: MouseEvent,\n\t) {\n\t\tsuper(event.type, event);\n\t}\n}\n\ntype MouseEventMap = {\n\t[evt in keyof HTMLElementEventMap]: HTMLElementEventMap[evt] extends MouseEvent\n\t\t? evt\n\t\t: never;\n};\ntype MouseEventTypes = MouseEventMap[keyof MouseEventMap];\ntype MouseEventListener = (\n\tthis: LyricLineEl,\n\tev: RawLyricLineMouseEvent,\n) => void;\n\nexport class LyricLineEl extends LyricLineBase {\n\tprivate element: HTMLElement = document.createElement(\"div\");\n\tprivate splittedWords: RealWord[] = [];\n\t// 标记是否已经构建了行内的实际 DOM(单词与动画等)\n\tprivate built = false;\n\n\t// 由 LyricPlayer 来设置\n\tlineSize: number[] = [0, 0];\n\n\tprivate renderMode = LyricLineRenderMode.SOLID;\n\n\tprivate currentBrightAlpha = 1.0;\n\tprivate currentDarkAlpha = 0.2;\n\n\tprivate targetBrightAlpha = 1.0;\n\tprivate targetDarkAlpha = 0.2;\n\n\t// Unicode 标准的 Grapheme Cluster 分割器\n\t// 用于正确处理 emoji、复合字符等\n\tprivate segmenter = new Intl.Segmenter(undefined, {\n\t\tgranularity: \"grapheme\",\n\t});\n\n\tconstructor(\n\t\tprivate lyricPlayer: DomLyricPlayer,\n\t\tprivate lyricLine: LyricLine = {\n\t\t\twords: [],\n\t\t\ttranslatedLyric: \"\",\n\t\t\tromanLyric: \"\",\n\t\t\tstartTime: 0,\n\t\t\tendTime: 0,\n\t\t\tisBG: false,\n\t\t\tisDuet: false,\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis._prevParentEl = lyricPlayer.getElement();\n\t\tlyricPlayer.resizeObserver.observe(this.element);\n\t\tthis.element.setAttribute(\"class\", styles.lyricLine);\n\t\tif (this.lyricLine.isBG) {\n\t\t\tthis.element.classList.add(styles.lyricBgLine);\n\t\t}\n\t\tif (this.lyricLine.isDuet) {\n\t\t\tthis.element.classList.add(styles.lyricDuetLine);\n\t\t}\n\t\tthis.lineTransforms.posY.setPosition(window.innerHeight * 2);\n\t\tthis.element.appendChild(document.createElement(\"div\")); // 歌词行\n\t\tthis.element.appendChild(document.createElement(\"div\")); // 翻译行\n\t\tthis.element.appendChild(document.createElement(\"div\")); // 音译行\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tconst trans = this.element.children[1] as HTMLDivElement;\n\t\tconst roman = this.element.children[2] as HTMLDivElement;\n\t\tmain.setAttribute(\"class\", styles.lyricMainLine);\n\t\ttrans.setAttribute(\"class\", styles.lyricSubLine);\n\t\troman.setAttribute(\"class\", styles.lyricSubLine);\n\t\t// 延迟构建具体行内容,进入可视区(含 overscan)时再构建\n\t\tthis.rebuildStyle();\n\t}\n\tprivate listenersMap = new Map<string, Set<MouseEventListener>>();\n\tprivate readonly onMouseEvent = (e: MouseEvent) => {\n\t\tconst wrapped = new RawLyricLineMouseEvent(this, e);\n\t\tfor (const listener of this.listenersMap.get(e.type) ?? []) {\n\t\t\tlistener.call(this, wrapped);\n\t\t}\n\t\tif (!this.dispatchEvent(wrapped) || wrapped.defaultPrevented) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\t};\n\n\taddMouseEventListener(\n\t\ttype: MouseEventTypes,\n\t\tcallback: MouseEventListener | null,\n\t\toptions?: boolean | AddEventListenerOptions | undefined,\n\t): void {\n\t\tif (callback) {\n\t\t\tconst listeners = this.listenersMap.get(type) ?? new Set();\n\t\t\tif (listeners.size === 0)\n\t\t\t\tthis.element.addEventListener(type, this.onMouseEvent, options);\n\t\t\tlisteners.add(callback);\n\t\t\tthis.listenersMap.set(type, listeners);\n\t\t}\n\t}\n\n\tremoveMouseEventListener(\n\t\ttype: MouseEventTypes,\n\t\tcallback: MouseEventListener | null,\n\t\toptions?: boolean | EventListenerOptions | undefined,\n\t): void {\n\t\tif (callback) {\n\t\t\tconst listeners = this.listenersMap.get(type);\n\t\t\tif (listeners) {\n\t\t\t\tlisteners.delete(callback);\n\t\t\t\tif (listeners.size === 0)\n\t\t\t\t\tthis.element.removeEventListener(type, this.onMouseEvent, options);\n\t\t\t}\n\t\t}\n\t}\n\n\tareWordsOnSameLine(word1: RealWord, word2: RealWord): boolean {\n\t\tif (word1?.mainElement && word2?.mainElement) {\n\t\t\tconst word1el = word1.mainElement;\n\t\t\tconst word2el = word2.mainElement;\n\n\t\t\tconst rect1 = word1el.getBoundingClientRect();\n\t\t\tconst rect2 = word2el.getBoundingClientRect();\n\n\t\t\t// 检查两个单词的顶部距离是否相等(或者差值很小)\n\t\t\tconst topDifference = Math.abs(rect1.top - rect2.top);\n\n\t\t\t// 如果顶部距离相差很小,可以认为它们在同一行上\n\t\t\treturn topDifference < 10;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate isEnabled = false;\n\tasync enable(\n\t\tmaskAnimationTime: number = this.lyricLine.startTime,\n\t\tshouldPlay = true,\n\t): Promise<void> {\n\t\tthis.isEnabled = true;\n\t\tthis.element.classList.add(styles.active);\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\n\t\tconst relativeTime = Math.max(\n\t\t\t0,\n\t\t\tmaskAnimationTime - this.lyricLine.startTime,\n\t\t);\n\t\tconst actualMaskTime =\n\t\t\tmaskAnimationTime === this.lyricLine.startTime\n\t\t\t\t? this.lyricPlayer.getCurrentTime()\n\t\t\t\t: maskAnimationTime;\n\n\t\tconst maskRelativeTime = Math.max(\n\t\t\t0,\n\t\t\tactualMaskTime - this.lyricLine.startTime,\n\t\t);\n\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\ta.currentTime = relativeTime;\n\t\t\t\ta.playbackRate = 1;\n\n\t\t\t\tconst timing = a.effect?.getComputedTiming();\n\t\t\t\tconst duration = (timing?.duration as number) || 0;\n\t\t\t\tconst delay = (timing?.delay as number) || 0;\n\t\t\t\tconst endTime = delay + duration;\n\n\t\t\t\tif (shouldPlay && relativeTime < endTime) {\n\t\t\t\t\ta.play();\n\t\t\t\t} else {\n\t\t\t\t\ta.pause();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\tconst t = Math.min(this.totalDuration, maskRelativeTime);\n\t\t\t\ta.currentTime = t;\n\t\t\t\ta.playbackRate = 1;\n\n\t\t\t\tconst timing = a.effect?.getComputedTiming();\n\t\t\t\tconst duration = (timing?.duration as number) || 0;\n\t\t\t\tconst delay = (timing?.delay as number) || 0;\n\t\t\t\tconst endTime = delay + duration;\n\n\t\t\t\tif (shouldPlay && t < endTime) {\n\t\t\t\t\ta.play();\n\t\t\t\t} else {\n\t\t\t\t\ta.pause();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tmain.classList.add(styles.active);\n\t}\n\n\tdisable(): void {\n\t\tthis.isEnabled = false;\n\t\tthis.element.classList.remove(styles.active);\n\t\tthis.renderMode = LyricLineRenderMode.SOLID;\n\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\tif (\n\t\t\t\t\ta.id === \"float-word\" ||\n\t\t\t\t\ta.id.includes(\"emphasize-word-float-only\")\n\t\t\t\t) {\n\t\t\t\t\ta.playbackRate = -1;\n\t\t\t\t\ta.play();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\ta.pause();\n\t\t\t}\n\t\t}\n\t\tmain.classList.remove(styles.active);\n\t}\n\n\tprivate lastWord?: RealWord;\n\n\tasync resume(): Promise<void> {\n\t\tif (!this.isEnabled) return;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\tif (\n\t\t\t\t\t!this.lastWord ||\n\t\t\t\t\tthis.splittedWords.indexOf(this.lastWord) <\n\t\t\t\t\t\tthis.splittedWords.indexOf(word)\n\t\t\t\t) {\n\t\t\t\t\tconst timing = a.effect?.getComputedTiming();\n\t\t\t\t\tconst duration = (timing?.duration as number) || 0;\n\t\t\t\t\tconst delay = (timing?.delay as number) || 0;\n\t\t\t\t\tconst endTime = delay + duration;\n\t\t\t\t\tconst currentTime = (a.currentTime as number) || 0;\n\n\t\t\t\t\tif (a.playState !== \"finished\" && currentTime < endTime) {\n\t\t\t\t\t\ta.play();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\tif (\n\t\t\t\t\t!this.lastWord ||\n\t\t\t\t\tthis.splittedWords.indexOf(this.lastWord) <\n\t\t\t\t\t\tthis.splittedWords.indexOf(word)\n\t\t\t\t) {\n\t\t\t\t\tconst timing = a.effect?.getComputedTiming();\n\t\t\t\t\tconst duration = (timing?.duration as number) || 0;\n\t\t\t\t\tconst delay = (timing?.delay as number) || 0;\n\t\t\t\t\tconst endTime = delay + duration;\n\n\t\t\t\t\tconst currentTime = (a.currentTime as number) || 0;\n\n\t\t\t\t\tif (a.playState !== \"finished\" && currentTime < endTime) {\n\t\t\t\t\t\ta.play();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tif (!this.isEnabled) return;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\ta.pause();\n\t\t\t}\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\ta.pause();\n\t\t\t}\n\t\t}\n\t}\n\tsetMaskAnimationState(maskAnimationTime = 0): void {\n\t\tconst t = maskAnimationTime - this.lyricLine.startTime;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\ta.currentTime = Math.min(this.totalDuration, Math.max(0, t));\n\t\t\t\ta.playbackRate = 1;\n\t\t\t\tif (t >= 0 && t < this.totalDuration) a.play();\n\t\t\t\telse a.pause();\n\t\t\t}\n\t\t}\n\t}\n\n\tgetLine(): LyricLine {\n\t\treturn this.lyricLine;\n\t}\n\t// private _hide = true;\n\tprivate _prevParentEl: HTMLElement;\n\tprivate lastStyle = \"\";\n\tshow(): void {\n\t\t// this._hide = false;\n\t\tif (!this.element.parentElement) {\n\t\t\tthis._prevParentEl.appendChild(this.element);\n\t\t\tthis.lyricPlayer.resizeObserver.observe(this.element);\n\t\t}\n\t\tif (!this.built) {\n\t\t\tthis.rebuildElement();\n\t\t\tthis.built = true;\n\t\t\tthis.updateMaskImageSync();\n\t\t}\n\t\tthis.rebuildStyle();\n\t}\n\thide(): void {\n\t\t// this._hide = true;\n\t\tif (this.element.parentElement) {\n\t\t\tthis._prevParentEl.removeChild(this.element);\n\t\t\tthis.lyricPlayer.resizeObserver.unobserve(this.element);\n\t\t}\n\t\tif (this.built) {\n\t\t\tthis.disposeElements();\n\t\t\tthis.built = false;\n\t\t}\n\t}\n\tprivate rebuildStyle() {\n\t\tlet style = \"\";\n\t\t// if (this.lyricPlayer.getEnableSpring()) {\n\t\tstyle += `transform:translateY(${this.lineTransforms.posY\n\t\t\t.getCurrentPosition()\n\t\t\t.toFixed(\n\t\t\t\t1,\n\t\t\t)}px) scale(${(this.lineTransforms.scale.getCurrentPosition() / 100).toFixed(4)});`;\n\t\tif (!this.lyricPlayer.getEnableSpring() && this.isInSight) {\n\t\t\tstyle += `transition-delay:${this.delay}ms;`;\n\t\t}\n\t\tstyle += `filter:blur(${Math.min(5, this.blur)}px);`;\n\t\tif (style !== this.lastStyle) {\n\t\t\tthis.lastStyle = style;\n\t\t\tthis.element.setAttribute(\"style\", style);\n\t\t}\n\t}\n\n\toverride rebuildElement(): void {\n\t\tthis.disposeElements();\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tconst trans = this.element.children[1] as HTMLDivElement;\n\t\tconst roman = this.element.children[2] as HTMLDivElement;\n\t\t// 非动态歌词,直接渲染整行与副行\n\t\tif (this.lyricPlayer._getIsNonDynamic()) {\n\t\t\tmain.innerText = this.lyricLine.words\n\t\t\t\t.map((w) => this.lyricPlayer.processObsceneWord(w))\n\t\t\t\t.join(\"\");\n\t\t\tthis.setSubLinesText(trans, roman);\n\t\t\treturn;\n\t\t}\n\n\t\tconst chunkedWords = chunkAndSplitLyricWords(this.lyricLine.words);\n\t\tconst hasRubyLine = this.lyricLine.words.some(\n\t\t\t(word) => (word.ruby?.length ?? 0) > 0,\n\t\t);\n\t\tconst hasRomanLine = this.lyricLine.words.some(\n\t\t\t(word) => (word.romanWord?.trim().length ?? 0) > 0,\n\t\t);\n\t\tmain.innerHTML = \"\";\n\n\t\tfor (const chunk of chunkedWords) {\n\t\t\tthis.buildWord(chunk, main, hasRubyLine, hasRomanLine);\n\t\t}\n\n\t\tthis.setSubLinesText(trans, roman);\n\t}\n\n\t/** 设置翻译与音译行文本 */\n\tprivate setSubLinesText(trans: HTMLDivElement, roman: HTMLDivElement) {\n\t\ttrans.innerText = this.lyricLine.translatedLyric;\n\t\troman.innerText = this.lyricLine.romanLyric;\n\t}\n\n\tprivate getRubyCharCount(word: LyricWord) {\n\t\treturn (word.ruby ?? []).reduce(\n\t\t\t(total, ruby) => total + ruby.word.length,\n\t\t\t0,\n\t\t);\n\t}\n\n\tprivate getRubySegments(word: LyricWord) {\n\t\treturn (word.ruby ?? []).filter(\n\t\t\t(ruby) => (ruby?.word?.trim().length ?? 0) > 0,\n\t\t);\n\t}\n\n\tprivate createWord(\n\t\tword: LyricWord,\n\t\tshouldEmphasize: boolean,\n\t\thasRubyLine: boolean,\n\t\thasRomanLine: boolean,\n\t): RealWord {\n\t\tconst mainWordEl = document.createElement(\"span\");\n\t\tconst subElements: HTMLSpanElement[] = [];\n\t\tconst romanWord = word.romanWord?.trim() ?? \"\";\n\t\tconst wordContainer = hasRubyLine\n\t\t\t? document.createElement(\"div\")\n\t\t\t: mainWordEl;\n\n\t\tif (hasRubyLine) {\n\t\t\tconst rubyWordEl = document.createElement(\"div\");\n\t\t\tconst rubySegments = this.getRubySegments(word);\n\t\t\tfor (const ruby of rubySegments) {\n\t\t\t\tconst rubyPartEl = document.createElement(\"span\");\n\t\t\t\trubyPartEl.innerText = ruby.word;\n\t\t\t\trubyPartEl.dataset.startTime = String(ruby.startTime);\n\t\t\t\trubyPartEl.dataset.endTime = String(ruby.endTime);\n\t\t\t\trubyWordEl.appendChild(rubyPartEl);\n\t\t\t}\n\t\t\trubyWordEl.classList.add(styles.rubyWord);\n\t\t\tmainWordEl.classList.add(styles.wordWithRuby);\n\t\t\twordContainer.classList.add(styles.wordBody);\n\t\t\tmainWordEl.appendChild(rubyWordEl);\n\t\t\tmainWordEl.appendChild(wordContainer);\n\t\t}\n\n\t\tconst displayWord = this.lyricPlayer.processObsceneWord(word);\n\n\t\tif (shouldEmphasize) {\n\t\t\tmainWordEl.classList.add(styles.emphasize);\n\t\t\tfor (const { segment } of this.segmenter.segment(displayWord.trim())) {\n\t\t\t\tconst charEl = document.createElement(\"span\");\n\t\t\t\tcharEl.innerText = segment;\n\t\t\t\tsubElements.push(charEl);\n\t\t\t\twordContainer.appendChild(charEl);\n\t\t\t}\n\t\t} else {\n\t\t\tif (hasRomanLine) {\n\t\t\t\tconst wordEl = document.createElement(\"div\");\n\t\t\t\twordEl.innerText = displayWord.trim();\n\t\t\t\twordContainer.appendChild(wordEl);\n\t\t\t} else if (romanWord.length === 0) {\n\t\t\t\twordContainer.innerText = displayWord.trim();\n\t\t\t}\n\t\t}\n\n\t\tif (hasRomanLine) {\n\t\t\tconst romanWordEl = document.createElement(\"div\");\n\t\t\tromanWordEl.innerText = romanWord.length > 0 ? romanWord : \"\\u00A0\";\n\t\t\tromanWordEl.classList.add(styles.romanWord);\n\t\t\twordContainer.appendChild(romanWordEl);\n\t\t}\n\n\t\tconst realWord: RealWord = {\n\t\t\t...word,\n\t\t\tmainElement: mainWordEl,\n\t\t\tsubElements: subElements,\n\t\t\telementAnimations: [this.initFloatAnimation(word, mainWordEl)],\n\t\t\tmaskAnimations: [],\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\tpadding: 0,\n\t\t\tshouldEmphasize: shouldEmphasize,\n\t\t};\n\n\t\treturn realWord;\n\t}\n\n\tprivate buildWord(\n\t\tinput: LyricWord | LyricWord[],\n\t\tmain: HTMLDivElement,\n\t\thasRubyLine: boolean,\n\t\thasRomanLine: boolean,\n\t) {\n\t\tconst chunk = Array.isArray(input) ? input : [input];\n\t\tif (chunk.length === 0) return;\n\n\t\tconst isPureSpace = chunk.every((w) => !w.word.trim());\n\t\tif (isPureSpace) {\n\t\t\tconst textContent = chunk.map((w) => w.word).join(\"\");\n\t\t\tmain.appendChild(document.createTextNode(textContent));\n\t\t\treturn;\n\t\t}\n\n\t\tconst merged = chunk.reduce(\n\t\t\t(a, b) => {\n\t\t\t\ta.endTime = Math.max(a.endTime, b.endTime);\n\t\t\t\ta.startTime = Math.min(a.startTime, b.startTime);\n\t\t\t\ta.word += b.word;\n\t\t\t\treturn a;\n\t\t\t},\n\t\t\t{\n\t\t\t\tword: \"\",\n\t\t\t\tromanWord: \"\",\n\t\t\t\tstartTime: Number.POSITIVE_INFINITY,\n\t\t\t\tendTime: Number.NEGATIVE_INFINITY,\n\t\t\t\twordType: \"normal\",\n\t\t\t\tobscene: false,\n\t\t\t} as LyricWord,\n\t\t);\n\n\t\tlet emp = chunk.some((word) => LyricLineBase.shouldEmphasize(word));\n\t\tif (!isCJK(merged.word)) {\n\t\t\temp = emp || LyricLineBase.shouldEmphasize(merged);\n\t\t}\n\n\t\tconst wrapperWordEl = document.createElement(\"span\");\n\t\twrapperWordEl.classList.add(styles.emphasizeWrapper);\n\n\t\tconst characterElements: HTMLElement[] = [];\n\n\t\tfor (const word of chunk) {\n\t\t\tif (!word.word.trim()) {\n\t\t\t\twrapperWordEl.appendChild(document.createTextNode(word.word));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst realWord = this.createWord(word, emp, hasRubyLine, hasRomanLine);\n\n\t\t\tif (emp) {\n\t\t\t\tcharacterElements.push(...realWord.subElements);\n\t\t\t}\n\n\t\t\tthis.splittedWords.push(realWord);\n\t\t\twrapperWordEl.appendChild(realWord.mainElement);\n\t\t}\n\n\t\tif (emp && this.splittedWords.length > 0) {\n\t\t\tconst lastWordOfChunk = this.splittedWords[this.splittedWords.length - 1];\n\t\t\tconst rubyCharCount = chunk.reduce(\n\t\t\t\t(total, word) => total + this.getRubyCharCount(word),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tlastWordOfChunk.elementAnimations.push(\n\t\t\t\t...this.initEmphasizeAnimation(\n\t\t\t\t\tmerged,\n\t\t\t\t\tcharacterElements,\n\t\t\t\t\tmerged.endTime - merged.startTime,\n\t\t\t\t\tmerged.startTime - this.lyricLine.startTime,\n\t\t\t\t\trubyCharCount,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tmain.appendChild(wrapperWordEl);\n\t}\n\n\tprivate initFloatAnimation(word: LyricWord, wordEl: HTMLSpanElement) {\n\t\tconst delay = word.startTime - this.lyricLine.startTime;\n\t\tconst duration = Math.max(1000, word.endTime - word.startTime);\n\t\tlet up = 0.05;\n\t\tif (this.lyricLine.isBG) {\n\t\t\tup *= 2;\n\t\t}\n\t\tconst a = wordEl.animate(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\ttransform: \"translateY(0px)\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttransform: `translateY(${-up}em)`,\n\t\t\t\t},\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: Number.isFinite(duration) ? duration : 0,\n\t\t\t\tdelay: Number.isFinite(delay) ? delay : 0,\n\t\t\t\tid: \"float-word\",\n\t\t\t\tcomposite: \"add\",\n\t\t\t\tfill: \"both\",\n\t\t\t\teasing: \"ease-out\",\n\t\t\t},\n\t\t);\n\t\ta.pause();\n\t\treturn a;\n\t}\n\t// 按照原 Apple Music 参考,强调效果只应用缩放、轻微左右位移和辉光效果,原主要的悬浮位移效果不变\n\t// 为了避免产生锯齿抖动感,使用 matrix3d 来实现缩放和位移\n\tprivate initEmphasizeAnimation(\n\t\tword: LyricWord,\n\t\tcharacterElements: HTMLElement[],\n\t\tduration: number,\n\t\tdelay: number,\n\t\trubyCharCount: number,\n\t): Animation[] {\n\t\tconst de = Math.max(0, delay);\n\t\tlet du = Math.max(1000, duration);\n\t\tconst anchorCharCount =\n\t\t\trubyCharCount > 0 ? rubyCharCount : Math.max(1, characterElements.length);\n\n\t\tlet result: Animation[] = [];\n\n\t\tlet amount = du / 2000;\n\t\tamount = amount > 1 ? Math.sqrt(amount) : amount ** 3;\n\t\tlet blur = du / 3000;\n\t\tblur = blur > 1 ? Math.sqrt(blur) : blur ** 3;\n\t\tamount *= 0.6;\n\t\tblur *= 0.5;\n\t\tif (\n\t\t\tthis.lyricLine.words.length > 0 &&\n\t\t\tword.word.includes(\n\t\t\t\tthis.lyricLine.words[this.lyricLine.words.length - 1].word,\n\t\t\t)\n\t\t) {\n\t\t\tamount *= 1.6;\n\t\t\tblur *= 1.5;\n\t\t\tdu *= 1.2;\n\t\t}\n\t\tamount = Math.min(1.2, amount);\n\t\tblur = Math.min(0.8, blur);\n\n\t\tconst animateDu = Number.isFinite(du) ? du : 0;\n\t\tconst empEasing = makeEmpEasing(EMP_EASING_MID);\n\n\t\tresult = characterElements.flatMap((el, i, arr) => {\n\t\t\tconst wordDe = de + (du / 2.5 / anchorCharCount) * i;\n\t\t\tconst result: Animation[] = [];\n\n\t\t\tconst frames: Keyframe[] = new Array(ANIMATION_FRAME_QUANTITY)\n\t\t\t\t.fill(0)\n\t\t\t\t.map((_, j) => {\n\t\t\t\t\tconst x = (j + 1) / ANIMATION_FRAME_QUANTITY;\n\t\t\t\t\tconst transX = empEasing(x);\n\t\t\t\t\tconst glowLevel = empEasing(x) * blur;\n\n\t\t\t\t\tconst mat = scaleMatrix4(createMatrix4(), 1 + transX * 0.1 * amount);\n\t\t\t\t\tconst offsetX = -transX * 0.03 * amount * (arr.length / 2 - i);\n\t\t\t\t\tconst offsetY = -transX * 0.025 * amount;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\toffset: x,\n\t\t\t\t\t\ttransform: `${matrix4ToCSS(\n\t\t\t\t\t\t\tmat,\n\t\t\t\t\t\t\t4,\n\t\t\t\t\t\t)} translate(${offsetX}em, ${offsetY}em)`,\n\t\t\t\t\t\ttextShadow: `0 0 ${Math.min(\n\t\t\t\t\t\t\t0.3,\n\t\t\t\t\t\t\tblur * 0.3,\n\t\t\t\t\t\t)}em rgba(255, 255, 255, ${glowLevel})`,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\tconst glow = el.animate(frames, {\n\t\t\t\tduration: animateDu,\n\t\t\t\tdelay: Number.isFinite(wordDe) ? wordDe : 0,\n\t\t\t\tid: `emphasize-word-${el.innerText}-${i}`,\n\t\t\t\titerations: 1,\n\t\t\t\tcomposite: \"replace\",\n\t\t\t\tfill: \"both\",\n\t\t\t});\n\t\t\tglow.onfinish = () => {\n\t\t\t\tglow.pause();\n\t\t\t};\n\t\t\tglow.pause();\n\t\t\tresult.push(glow);\n\n\t\t\tconst floatFrame: Keyframe[] = new Array(ANIMATION_FRAME_QUANTITY)\n\t\t\t\t.fill(0)\n\t\t\t\t.map((_, j) => {\n\t\t\t\t\tconst x = (j + 1) / ANIMATION_FRAME_QUANTITY;\n\t\t\t\t\tlet y = Math.sin(x * Math.PI);\n\t\t\t\t\t// y = x < 0.5 ? y : Math.max(y, 1.0);\n\t\t\t\t\tif (this.lyricLine.isBG) {\n\t\t\t\t\t\ty *= 2;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\toffset: x,\n\t\t\t\t\t\ttransform: `translateY(${-y * 0.05}em)`,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\tconst float = el.animate(floatFrame, {\n\t\t\t\tduration: animateDu * 1.4,\n\t\t\t\tdelay: Number.isFinite(wordDe) ? wordDe - 400 : 0,\n\t\t\t\tid: \"emphasize-word-float\",\n\t\t\t\titerations: 1,\n\t\t\t\tcomposite: \"add\",\n\t\t\t\tfill: \"both\",\n\t\t\t});\n\t\t\tfloat.onfinish = () => {\n\t\t\t\tfloat.pause();\n\t\t\t};\n\t\t\tfloat.pause();\n\t\t\tresult.push(float);\n\n\t\t\treturn result;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tprivate get totalDuration() {\n\t\treturn this.lyricLine.endTime - this.lyricLine.startTime;\n\t}\n\n\toverride onLineSizeChange(_size: [number, number]): void {\n\t\tthis.updateMaskImageSync();\n\t}\n\tupdateMaskImageSync(): void {\n\t\tfor (const word of this.splittedWords) {\n\t\t\tconst el = word.mainElement;\n\t\t\tif (el) {\n\t\t\t\tword.padding = Number.parseFloat(getComputedStyle(el).paddingLeft);\n\t\t\t\tword.width = el.clientWidth - word.padding * 2;\n\t\t\t\tword.height = el.clientHeight - word.padding * 2;\n\t\t\t} else {\n\t\t\t\tword.width = 0;\n\t\t\t\tword.height = 0;\n\t\t\t\tword.padding = 0;\n\t\t\t}\n\t\t}\n\t\tif (this.lyricPlayer.supportMaskImage) {\n\t\t\tthis.generateWebAnimationBasedMaskImage();\n\t\t} else {\n\t\t\tthis.generateCalcBasedMaskImage();\n\t\t}\n\t\tif (this.isEnabled) {\n\t\t\tconst isPlayerRunning = this.lyricPlayer.getIsPlaying?.() ?? true;\n\t\t\tthis.enable(this.lyricPlayer.getCurrentTime(), isPlayerRunning);\n\t\t}\n\t}\n\n\tprivate generateCalcBasedMaskImage() {\n\t\tfor (const word of this.splittedWords) {\n\t\t\tconst wordEl = word.mainElement;\n\t\t\tif (wordEl) {\n\t\t\t\tword.width = wordEl.clientWidth;\n\t\t\t\tword.height = wordEl.clientHeight;\n\t\t\t\tconst fadeWidth = word.height * this.lyricPlayer.getWordFadeWidth();\n\t\t\t\tconst [maskImage, totalAspect] = generateFadeGradient(\n\t\t\t\t\tfadeWidth / word.width,\n\t\t\t\t);\n\t\t\t\tconst totalAspectStr = `${totalAspect * 100}% 100%`;\n\t\t\t\tif (this.lyricPlayer.supportMaskImage) {\n\t\t\t\t\twordEl.style.maskImage = maskImage;\n\t\t\t\t\twordEl.style.maskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.maskOrigin = \"left\";\n\t\t\t\t\twordEl.style.maskSize = totalAspectStr;\n\t\t\t\t} else {\n\t\t\t\t\twordEl.style.webkitMaskImage = maskImage;\n\t\t\t\t\twordEl.style.webkitMaskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.webkitMaskOrigin = \"left\";\n\t\t\t\t\twordEl.style.webkitMaskSize = totalAspectStr;\n\t\t\t\t}\n\t\t\t\tconst w = word.width + fadeWidth;\n\t\t\t\tconst maskPos = `clamp(${-w}px,calc(${-w}px + (var(--amll-player-time) - ${\n\t\t\t\t\tword.startTime\n\t\t\t\t})*${\n\t\t\t\t\tw / Math.abs(word.endTime - word.startTime)\n\t\t\t\t}px),0px) 0px, left top`;\n\t\t\t\twordEl.style.maskPosition = maskPos;\n\t\t\t\twordEl.style.webkitMaskPosition = maskPos;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate generateWebAnimationBasedMaskImage() {\n\t\t// 因为歌词行有可能比行内单词的结束时间早,有可能导致过渡动画提早停止出现瑕疵\n\t\t// 所以要以单词的结束时间为准\n\t\tconst totalFadeDuration =\n\t\t\tMath.max(\n\t\t\t\tthis.splittedWords.reduce((pv, w) => Math.max(w.endTime, pv), 0),\n\t\t\t\tthis.lyricLine.endTime,\n\t\t\t) - this.lyricLine.startTime;\n\t\tthis.splittedWords.forEach((word, i) => {\n\t\t\tconst wordEl = word.mainElement;\n\t\t\tif (wordEl) {\n\t\t\t\tconst fadeWidth = word.height * this.lyricPlayer.getWordFadeWidth();\n\t\t\t\tconst [maskImage, totalAspect] = generateFadeGradient(\n\t\t\t\t\tfadeWidth / (word.width + word.padding * 2),\n\t\t\t\t);\n\t\t\t\tconst totalAspectStr = `${totalAspect * 100}% 100%`;\n\t\t\t\tif (this.lyricPlayer.supportMaskImage) {\n\t\t\t\t\twordEl.style.maskImage = maskImage;\n\t\t\t\t\twordEl.style.maskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.maskOrigin = \"left\";\n\t\t\t\t\twordEl.style.maskSize = totalAspectStr;\n\t\t\t\t} else {\n\t\t\t\t\twordEl.style.webkitMaskImage = maskImage;\n\t\t\t\t\twordEl.style.webkitMaskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.webkitMaskOrigin = \"left\";\n\t\t\t\t\twordEl.style.webkitMaskSize = totalAspectStr;\n\t\t\t\t}\n\t\t\t\t// 为了尽可能将渐变动画在相连的每个单词间近似衔接起来\n\t\t\t\t// 要综合每个单词的效果时间和间隙生成动画帧数组\n\t\t\t\tconst widthBeforeSelf =\n\t\t\t\t\tthis.splittedWords.slice(0, i).reduce((a, b) => a + b.width, 0) +\n\t\t\t\t\t(this.splittedWords[0] ? fadeWidth : 0);\n\t\t\t\tconst minOffset = -(word.width + word.padding * 2 + fadeWidth);\n\t\t\t\tconst clampOffset = (x: number) => Math.max(minOffset, Math.min(0, x));\n\t\t\t\tlet curPos = -widthBeforeSelf - word.width - word.padding - fadeWidth;\n\t\t\t\tlet timeOffset = 0;\n\t\t\t\tconst frames: Keyframe[] = [];\n\t\t\t\tlet lastPos = curPos;\n\t\t\t\tlet lastTime = 0;\n\t\t\t\tconst pushFrame = () => {\n\t\t\t\t\t// 此处如果添加过渡函数,会导致单词时序不准确,所以不添加\n\t\t\t\t\t// const easing = \"cubic-bezier(.33,.12,.83,.9)\";\n\t\t\t\t\tconst moveOffset = curPos - lastPos;\n\t\t\t\t\tconst time = Math.max(0, Math.min(1, timeOffset));\n\t\t\t\t\tconst duration = time - lastTime;\n\t\t\t\t\tconst d = Math.abs(duration / moveOffset);\n\t\t\t\t\t// 因为有可能会和之前的动画有边界\n\t\t\t\t\tif (curPos > minOffset && lastPos < minOffset) {\n\t\t\t\t\t\tconst staticTime = Math.abs(lastPos - minOffset) * d;\n\t\t\t\t\t\tconst value = `${clampOffset(lastPos)}px 0`;\n\t\t\t\t\t\tconst frame: Keyframe = {\n\t\t\t\t\t\t\toffset: lastTime + staticTime,\n\t\t\t\t\t\t\tmaskPosition: value,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tframes.push(frame);\n\t\t\t\t\t}\n\t\t\t\t\tif (curPos > 0 && lastPos < 0) {\n\t\t\t\t\t\tconst staticTime = Math.abs(lastPos) * d;\n\t\t\t\t\t\tconst value = `${clampOffset(curPos)}px 0`;\n\t\t\t\t\t\tconst frame: Keyframe = {\n\t\t\t\t\t\t\toffset: lastTime + staticTime,\n\t\t\t\t\t\t\tmaskPosition: value,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tframes.push(frame);\n\t\t\t\t\t}\n\t\t\t\t\tconst value = `${clampOffset(curPos)}px 0`;\n\t\t\t\t\tconst frame: Keyframe = {\n\t\t\t\t\t\toffset: time,\n\t\t\t\t\t\tmaskPosition: value,\n\t\t\t\t\t};\n\t\t\t\t\tframes.push(frame);\n\t\t\t\t\tlastPos = curPos;\n\t\t\t\t\tlastTime = time;\n\t\t\t\t};\n\t\t\t\tpushFrame();\n\t\t\t\tlet lastTimeStamp = 0;\n\t\t\t\tthis.splittedWords.forEach((otherWord, j) => {\n\t\t\t\t\t// 停顿\n\t\t\t\t\t{\n\t\t\t\t\t\tconst curTimeStamp = otherWord.startTime - this.lyricLine.startTime;\n\t\t\t\t\t\tconst staticDuration = curTimeStamp - lastTimeStamp;\n\t\t\t\t\t\ttimeOffset += staticDuration / totalFadeDuration;\n\t\t\t\t\t\tif (staticDuration > 0) pushFrame();\n\t\t\t\t\t\tlastTimeStamp = curTimeStamp;\n\t\t\t\t\t}\n\t\t\t\t\t// 移动\n\t\t\t\t\t{\n\t\t\t\t\t\tconst fadeDuration = Math.max(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\totherWord.endTime - otherWord.startTime,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst rubySegments = this.getRubySegments(otherWord);\n\t\t\t\t\t\tconst rubyCharCount = rubySegments.reduce(\n\t\t\t\t\t\t\t(total, ruby) => total + ruby.word.length,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (rubyCharCount > 0) {\n\t\t\t\t\t\t\tconst widthPerChar = otherWord.width / rubyCharCount;\n\t\t\t\t\t\t\tlet charIndex = 0;\n\t\t\t\t\t\t\tfor (const ruby of rubySegments) {\n\t\t\t\t\t\t\t\tconst rubyStartTime = Number.isFinite(ruby.startTime)\n\t\t\t\t\t\t\t\t\t? ruby.startTime\n\t\t\t\t\t\t\t\t\t: otherWord.startTime;\n\t\t\t\t\t\t\t\tconst rubyEndTime = Number.isFinite(ruby.endTime)\n\t\t\t\t\t\t\t\t\t? ruby.endTime\n\t\t\t\t\t\t\t\t\t: otherWord.endTime;\n\t\t\t\t\t\t\t\tconst rubyStart = Math.max(rubyStartTime, otherWord.startTime);\n\t\t\t\t\t\t\t\tconst rubyEnd = Math.min(\n\t\t\t\t\t\t\t\t\tMath.max(rubyEndTime, rubyStart),\n\t\t\t\t\t\t\t\t\totherWord.endTime,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst rubyStartStamp = rubyStart - this.lyricLine.startTime;\n\t\t\t\t\t\t\t\tconst rubyStaticDuration = rubyStartStamp - lastTimeStamp;\n\t\t\t\t\t\t\t\ttimeOffset += rubyStaticDuration / totalFadeDuration;\n\t\t\t\t\t\t\t\tif (rubyStaticDuration > 0) pushFrame();\n\t\t\t\t\t\t\t\tlastTimeStamp = rubyStartStamp;\n\t\t\t\t\t\t\t\tconst rubyDuration = Math.max(0, rubyEnd - rubyStart);\n\t\t\t\t\t\t\t\tconst perCharDuration = rubyDuration / ruby.word.length;\n\t\t\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\t\t\tlet rubyCharIndex = 0;\n\t\t\t\t\t\t\t\t\trubyCharIndex < ruby.word.length;\n\t\t\t\t\t\t\t\t\trubyCharIndex++\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\ttimeOffset += perCharDuration / totalFadeDuration;\n\t\t\t\t\t\t\t\t\tcurPos += widthPerChar;\n\t\t\t\t\t\t\t\t\tif (j === 0 && charIndex === 0) {\n\t\t\t\t\t\t\t\t\t\tcurPos += fadeWidth * 1.5;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tj === this.splittedWords.length - 1 &&\n\t\t\t\t\t\t\t\t\t\tcharIndex === rubyCharCount - 1\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tcurPos += fadeWidth * 0.5;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (perCharDuration > 0) pushFrame();\n\t\t\t\t\t\t\t\t\tlastTimeStamp += perCharDuration;\n\t\t\t\t\t\t\t\t\tcharIndex++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst wordEndStamp = Math.max(\n\t\t\t\t\t\t\t\totherWord.endTime - this.lyricLine.startTime,\n\t\t\t\t\t\t\t\tlastTimeStamp,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst wordTailDuration = wordEndStamp - lastTimeStamp;\n\t\t\t\t\t\t\ttimeOffset += wordTailDuration / totalFadeDuration;\n\t\t\t\t\t\t\tif (wordTailDuration > 0) pushFrame();\n\t\t\t\t\t\t\tlastTimeStamp = wordEndStamp;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst segmentCount = 1;\n\t\t\t\t\t\t\tconst segmentWidth = otherWord.width / segmentCount;\n\t\t\t\t\t\t\tconst segmentDuration = fadeDuration / segmentCount;\n\t\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\t\tlet segmentIndex = 0;\n\t\t\t\t\t\t\t\tsegmentIndex < segmentCount;\n\t\t\t\t\t\t\t\tsegmentIndex++\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\ttimeOffset += segmentDuration / totalFadeDuration;\n\t\t\t\t\t\t\t\tcurPos += segmentWidth;\n\t\t\t\t\t\t\t\tif (j === 0 && segmentIndex === 0) {\n\t\t\t\t\t\t\t\t\tcurPos += fadeWidth * 1.5;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tj === this.splittedWords.length - 1 &&\n\t\t\t\t\t\t\t\t\tsegmentIndex === segmentCount - 1\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tcurPos += fadeWidth * 0.5;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (segmentDuration > 0) pushFrame();\n\t\t\t\t\t\t\t\tlastTimeStamp += segmentDuration;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\t\ta.cancel();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\t// TODO: 如果此处动画帧计算出错,需要一个后备方案\n\t\t\t\t\t// 此处如果添加过渡函数,会导致单词时序不准确,所以不添加\n\t\t\t\t\tconst ani = wordEl.animate(frames, {\n\t\t\t\t\t\tduration: totalFadeDuration || 1,\n\t\t\t\t\t\tid: `fade-word-${word.word}-${i}`,\n\t\t\t\t\t\tfill: \"both\",\n\t\t\t\t\t});\n\t\t\t\t\tani.pause();\n\t\t\t\t\tword.maskAnimations = [ani];\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.warn(\"应用渐变动画发生错误\", frames, totalFadeDuration, err);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tgetElement(): HTMLElement {\n\t\treturn this.element;\n\t}\n\n\tprivate updateMaskAlphaTargets(scale: number) {\n\t\tconst factor = Math.max(0.0, Math.min(1.0, (scale - 0.97) / 0.03));\n\t\tconst dynamicDarkAlpha = factor * 0.2 + 0.2;\n\t\tconst dynamicBrightAlpha = factor * 0.8 + 0.2;\n\n\t\tif (this.renderMode === LyricLineRenderMode.SOLID) {\n\t\t\tthis.targetBrightAlpha = dynamicDarkAlpha;\n\t\t\tthis.targetDarkAlpha = dynamicDarkAlpha;\n\t\t} else {\n\t\t\tthis.targetBrightAlpha = dynamicBrightAlpha;\n\t\t\tthis.targetDarkAlpha = dynamicDarkAlpha;\n\t\t}\n\t}\n\n\tprivate applyAlphaToDom(delta: number) {\n\t\tconst dt = delta || 0.016;\n\t\tconst ATTACK_SPEED = 50.0;\n\t\tconst RELEASE_SPEED = 7.0;\n\t\tconst getFactor = (speed: number) => 1 - Math.exp(-speed * dt);\n\n\t\t// 根据即将变亮还是变暗选择速度\n\t\t// 如果即将变亮,让速度非常快,以免播放到第一个字的时候透明度还在慢慢增加导致看不清\n\t\tconst isBrightening = this.targetBrightAlpha > this.currentBrightAlpha;\n\t\tconst brightSpeed = isBrightening ? ATTACK_SPEED : RELEASE_SPEED;\n\t\tconst brightFactor = getFactor(brightSpeed);\n\n\t\tif (Math.abs(this.targetBrightAlpha - this.currentBrightAlpha) < 0.001) {\n\t\t\tthis.currentBrightAlpha = this.targetBrightAlpha;\n\t\t} else {\n\t\t\tthis.currentBrightAlpha +=\n\t\t\t\t(this.targetBrightAlpha - this.currentBrightAlpha) * brightFactor;\n\t\t}\n\n\t\tconst isDarkening = this.targetDarkAlpha > this.currentDarkAlpha;\n\t\tconst darkSpeed = isDarkening ? ATTACK_SPEED : RELEASE_SPEED;\n\t\tconst darkFactor = getFactor(darkSpeed);\n\n\t\tif (Math.abs(this.targetDarkAlpha - this.currentDarkAlpha) < 0.001) {\n\t\t\tthis.currentDarkAlpha = this.targetDarkAlpha;\n\t\t} else {\n\t\t\tthis.currentDarkAlpha +=\n\t\t\t\t(this.targetDarkAlpha - this.currentDarkAlpha) * darkFactor;\n\t\t}\n\n\t\tthis.element.style.setProperty(\n\t\t\t\"--bright-mask-alpha\",\n\t\t\tthis.currentBrightAlpha.toFixed(3),\n\t\t);\n\t\tthis.element.style.setProperty(\n\t\t\t\"--dark-mask-alpha\",\n\t\t\tthis.currentDarkAlpha.toFixed(3),\n\t\t);\n\t}\n\n\toverride setTransform(\n\t\ttop: number = this.top,\n\t\tscale: number = this.scale,\n\t\topacity = 1,\n\t\tblur = 0,\n\t\tforce = false,\n\t\tdelay = 0,\n\t\tmode: LyricLineRenderMode = LyricLineRenderMode.SOLID,\n\t): void {\n\t\tsuper.setTransform(top, scale, opacity, blur, force, delay);\n\t\tthis.renderMode = mode;\n\t\tconst beforeInSight = this.isInSight;\n\t\tconst enableSpring = this.lyricPlayer.getEnableSpring();\n\t\tthis.top = top;\n\t\tthis.scale = scale;\n\t\tthis.delay = (delay * 1000) | 0;\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\t// main.style.opacity = `${opacity *\n\t\t// \t(!this.hasFaded ? 1 : this.lyricPlayer._getIsNonDynamic() ? 1 : 0.3)\n\t\t// \t}`;\n\t\tmain.style.opacity = `${opacity}`;\n\t\tif (force || !enableSpring) {\n\t\t\tthis.blur = Math.min(32, blur);\n\t\t\t// if (force) this.element.classList.add(styles.tmpDisableTransition);\n\t\t\t// this.lineWebAnimationTransforms.posX.setTargetPosition(left);\n\t\t\t// this.lineWebAnimationTransforms.posY.setTargetPosition(top);\n\t\t\t// this.lineWebAnimationTransforms.scale.setTargetPosition(scale);\n\t\t\tthis.lineTransforms.posY.setPosition(top);\n\t\t\tthis.lineTransforms.scale.setPosition(scale);\n\t\t\tif (!enableSpring) {\n\t\t\t\tconst afterInSight = this.isInSight;\n\t\t\t\tif (beforeInSight || afterInSight) {\n\t\t\t\t\tthis.show();\n\t\t\t\t} else {\n\t\t\t\t\tthis.hide();\n\t\t\t\t}\n\t\t\t} else this.rebuildStyle();\n\t\t\t// if (force)\n\t\t\t// \trequestAnimationFrame(() => {\n\t\t\t// \t\tthis.element.classList.remove(styles.tmpDisableTransition);\n\t\t\t// \t});\n\t\t\tconst currentScale = this.lineTransforms.scale.getCurrentPosition();\n\t\t\tthis.updateMaskAlphaTargets(currentScale / 100);\n\t\t\tthis.currentBrightAlpha = this.targetBrightAlpha;\n\t\t\tthis.currentDarkAlpha = this.targetDarkAlpha;\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--bright-mask-alpha\",\n\t\t\t\tString(this.currentBrightAlpha),\n\t\t\t);\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--dark-mask-alpha\",\n\t\t\t\tString(this.currentDarkAlpha),\n\t\t\t);\n\t\t} else {\n\t\t\t// this.lineWebAnimationTransforms.posX.stop();\n\t\t\t// this.lineWebAnimationTransforms.posY.stop();\n\t\t\t// this.lineWebAnimationTransforms.scale.stop();\n\t\t\tthis.lineTransforms.posY.setTargetPosition(top, delay);\n\t\t\tthis.lineTransforms.scale.setTargetPosition(scale);\n\t\t\tif (this.blur !== Math.min(5, blur)) {\n\t\t\t\tthis.blur = Math.min(5, blur);\n\t\t\t\tconst roundedBlur = blur.toFixed(3);\n\t\t\t\tthis.element.style.filter = `blur(${roundedBlur}px)`;\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate(delta = 0): void {\n\t\tif (!this.lyricPlayer.getEnableSpring()) return;\n\n\t\tthis.lineTransforms.posY.update(delta);\n\t\tthis.lineTransforms.scale.update(delta);\n\n\t\tif (this.isInSight) {\n\t\t\tthis.show();\n\t\t} else {\n\t\t\tthis.hide();\n\t\t}\n\n\t\tconst currentScale = this.lineTransforms.scale.getCurrentPosition() / 100;\n\t\tthis.updateMaskAlphaTargets(currentScale);\n\t\tthis.applyAlphaToDom(delta);\n\t}\n\n\t_getDebugTargetPos(): string {\n\t\treturn `[位移: ${this.top}; 缩放: ${this.scale}; 延时: ${this.delay}]`;\n\t}\n\n\tget isInSight(): boolean {\n\t\tconst t = this.lineTransforms.posY.getCurrentPosition();\n\t\tconst h = this.lyricPlayer.lyricLinesSize.get(this)?.[1] ?? 0;\n\t\tconst b = t + h;\n\t\tconst pb = this.lyricPlayer.size[1];\n\t\tconst ov = this.lyricPlayer.getOverscanPx();\n\t\treturn !(t > pb + h + ov || b < -h - ov);\n\t}\n\tprivate disposeElements() {\n\t\tfor (const realWord of this.splittedWords) {\n\t\t\tfor (const a of realWord.elementAnimations) {\n\t\t\t\ta.cancel();\n\t\t\t}\n\t\t\tfor (const a of realWord.maskAnimations) {\n\t\t\t\ta.cancel();\n\t\t\t}\n\t\t\tfor (const sub of realWord.subElements) {\n\t\t\t\tsub.remove();\n\t\t\t\tsub.parentNode?.removeChild(sub);\n\t\t\t}\n\t\t\trealWord.elementAnimations = [];\n\t\t\trealWord.maskAnimations = [];\n\t\t\trealWord.subElements = [];\n\t\t\tif (realWord.mainElement?.parentNode) {\n\t\t\t\trealWord.mainElement.parentNode.removeChild(realWord.mainElement);\n\t\t\t}\n\t\t}\n\t\tthis.splittedWords = [];\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tconst trans = this.element.children[1] as HTMLDivElement;\n\t\tconst roman = this.element.children[2] as HTMLDivElement;\n\t\tif (main) main.innerHTML = \"\";\n\t\tif (trans) trans.innerHTML = \"\";\n\t\tif (roman) roman.innerHTML = \"\";\n\t}\n\toverride dispose(): void {\n\t\tthis.disposeElements();\n\t\tthis.lyricPlayer.resizeObserver.unobserve(this.element);\n\t\tthis.element.remove();\n\t}\n}\n","/**\n * @fileoverview\n * 一个播放歌词的组件\n * @author SteveXMH\n */\n\nimport type { LyricLine } from \"../../interfaces.ts\";\nimport \"../../styles/index.css\";\nimport styles from \"../../styles/lyric-player.module.css\";\nimport { type LyricLineBase, LyricPlayerBase } from \"../base.ts\";\nimport { LyricLineEl, type RawLyricLineMouseEvent } from \"./lyric-line.ts\";\n\n/**\n * 歌词行鼠标相关事件,可以获取到歌词行的索引和歌词行元素\n */\nexport class LyricLineMouseEvent extends MouseEvent {\n\tconstructor(\n\t\t/**\n\t\t * 歌词行索引\n\t\t */\n\t\tpublic readonly lineIndex: number,\n\t\t/**\n\t\t * 歌词行元素\n\t\t */\n\t\tpublic readonly line: LyricLineBase,\n\t\tevent: MouseEvent,\n\t) {\n\t\tsuper(`line-${event.type}`, event);\n\t}\n}\n\nexport type LyricLineMouseEventListener = (evt: LyricLineMouseEvent) => void;\n\n/**\n * 歌词播放组件,本框架的核心组件\n *\n * 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施\n */\nexport class DomLyricPlayer extends LyricPlayerBase {\n\toverride currentLyricLineObjects: LyricLineEl[] = [];\n\n\toverride onResize(): void {\n\t\tconst computedStyles = getComputedStyle(this.element);\n\t\tthis._baseFontSize = Number.parseFloat(computedStyles.fontSize);\n\t\tthis.rebuildStyle();\n\t}\n\n\treadonly supportPlusLighter: boolean = CSS.supports(\n\t\t\"mix-blend-mode\",\n\t\t\"plus-lighter\",\n\t);\n\treadonly supportMaskImage: boolean = CSS.supports(\"mask-image\", \"none\");\n\treadonly innerSize: [number, number] = [0, 0];\n\tprivate readonly onLineClickedHandler = (e: RawLyricLineMouseEvent) => {\n\t\tconst evt = new LyricLineMouseEvent(\n\t\t\tthis.lyricLinesIndexes.get(e.line) ?? -1,\n\t\t\te.line,\n\t\t\te,\n\t\t);\n\t\tif (!this.dispatchEvent(evt)) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\t};\n\t/**\n\t * 是否为非逐词歌词\n\t * @internal\n\t */\n\t_getIsNonDynamic(): boolean {\n\t\treturn this.isNonDynamic;\n\t}\n\tprivate _baseFontSize = Number.parseFloat(\n\t\tgetComputedStyle(this.element).fontSize,\n\t);\n\tpublic get baseFontSize(): number {\n\t\treturn this._baseFontSize;\n\t}\n\tconstructor() {\n\t\tsuper();\n\t\tthis.onResize();\n\t\tthis.element.classList.add(\"amll-lyric-player\", \"dom\");\n\t\tif (this.disableSpring) {\n\t\t\tthis.element.classList.add(styles.disableSpring);\n\t\t}\n\t}\n\n\tprivate rebuildStyle() {\n\t\t// const width = this.innerSize[0];\n\t\t// const height = this.innerSize[1];\n\t\t// this.element.style.setProperty(\"--amll-lp-width\", `${width.toFixed(4)}px`);\n\t\t// this.element.style.setProperty(\n\t\t// \t\"--amll-lp-height\",\n\t\t// \t`${height.toFixed(4)}px`,\n\t\t// );\n\t}\n\n\toverride setWordFadeWidth(value = 0.5): void {\n\t\tsuper.setWordFadeWidth(value);\n\t\tfor (const el of this.currentLyricLineObjects) {\n\t\t\tel.updateMaskImageSync();\n\t\t}\n\t}\n\n\t/**\n\t * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误\n\t * @param lines 歌词数组\n\t * @param initialTime 初始时间,默认为 0\n\t */\n\toverride setLyricLines(lines: LyricLine[], initialTime = 0): void {\n\t\tsuper.setLyricLines(lines, initialTime);\n\t\tif (this.hasDuetLine) {\n\t\t\tthis.element.classList.add(styles.hasDuetLine);\n\t\t} else {\n\t\t\tthis.element.classList.remove(styles.hasDuetLine);\n\t\t}\n\t\tif (!this.supportMaskImage) {\n\t\t\tthis.element.style.setProperty(\"--amll-player-time\", `${initialTime}`);\n\t\t}\n\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.removeMouseEventListener(\"click\", this.onLineClickedHandler);\n\t\t\tline.removeMouseEventListener(\"contextmenu\", this.onLineClickedHandler);\n\t\t\tline.dispose();\n\t\t}\n\n\t\t// 创建新的歌词行元素\n\t\tthis.currentLyricLineObjects = this.processedLines.map((line, i) => {\n\t\t\tconst lineEl = new LyricLineEl(this, line);\n\t\t\tlineEl.addMouseEventListener(\"click\", this.onLineClickedHandler);\n\t\t\tlineEl.addMouseEventListener(\"contextmenu\", this.onLineClickedHandler);\n\t\t\t// 不立即挂载到 DOM,进入视图(含 overscan)后在 LyricLineEl 内部挂载\n\t\t\tthis.lyricLinesIndexes.set(lineEl, i);\n\t\t\t// 仍需建立元素到行对象的映射,供 ResizeObserver 使用\n\t\t\tthis.lyricLineElementMap.set(lineEl.getElement(), lineEl);\n\t\t\treturn lineEl;\n\t\t});\n\n\t\tthis.setLinePosXSpringParams({});\n\t\tthis.setLinePosYSpringParams({});\n\t\tthis.setLineScaleSpringParams({});\n\t\tthis.calcLayout(true);\n\t\t// 触发一次更新以便立即挂载在视区/overscan 内的行元素\n\t\tthis.update(0);\n\t}\n\n\toverride pause(): void {\n\t\tsuper.pause();\n\t\tthis.element.classList.remove(\"playing\");\n\t\tthis.interludeDots.pause();\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.pause();\n\t\t}\n\t}\n\n\toverride resume(): void {\n\t\tsuper.resume();\n\t\tthis.element.classList.add(\"playing\");\n\t\tthis.interludeDots.resume();\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.resume();\n\t\t}\n\t}\n\n\toverride update(delta = 0): void {\n\t\tif (!this.initialLayoutFinished) return;\n\t\tsuper.update(delta);\n\t\tif (!this.supportMaskImage) {\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--amll-player-time\",\n\t\t\t\t`${this.currentTime}`,\n\t\t\t);\n\t\t}\n\t\tif (!this.isPageVisible) return;\n\t\tconst deltaS = delta / 1000;\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.update(deltaS);\n\t\t}\n\t}\n\n\toverride dispose(): void {\n\t\tsuper.dispose();\n\t\tthis.element.remove();\n\t\tfor (const el of this.currentLyricLineObjects) {\n\t\t\tel.dispose();\n\t\t}\n\t\tthis.bottomLine.dispose();\n\t\tthis.interludeDots.dispose();\n\t}\n}\n","// biome-ignore lint/suspicious/noExplicitAny: for debounce function\nexport function debounce<T extends (...args: any) => any>(\n\tcb: T,\n\twait = 20,\n): (...args: Parameters<T>) => void {\n\tlet h: ReturnType<typeof setTimeout> | undefined;\n\tconst callable = (...args: Parameters<T>) => {\n\t\tclearTimeout(h);\n\t\th = setTimeout(() => cb(...args), wait);\n\t};\n\treturn callable;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: function can be any\nexport function debounceFrame<T extends (...args: any) => any>(\n\tcb: T,\n\tframeTime = 1,\n): (...args: Parameters<T>) => void {\n\tlet h = 0;\n\tlet ft = frameTime;\n\tconst callable = (...args: Parameters<T>) => {\n\t\tft = frameTime;\n\t\tcancelAnimationFrame(h);\n\t\tconst onCB = () => {\n\t\t\tif (--ft <= 0) {\n\t\t\t\tcb(...args);\n\t\t\t} else {\n\t\t\t\th = requestAnimationFrame(onCB);\n\t\t\t}\n\t\t};\n\t\th = requestAnimationFrame(onCB);\n\t};\n\treturn callable;\n}\n","/*\n 给各个内部元素使用的样式\n*/\n\n/* 给每行歌词应用的样式 */\n.lyricLine {\n\twidth: var(--amll-lp-width, 100%);\n\tmin-width: var(--amll-lp-width, 100%);\n\tmax-width: var(--amll-lp-width, 100%);\n\twidth: 100%;\n\theight: fit-content;\n\tpadding: 2vh 1em;\n\tcontain: content;\n\ttransition:\n\t\topacity 0.25s,\n\t\tfilter 0.2s,\n\t\tbackground-color 0.25s,\n\t\tbox-shadow 0.25s;\n\tbox-sizing: border-box;\n\tborder-radius: 0.25em;\n\n\tpadding-left: 1em;\n\tpadding-right: 1em;\n\n\t&:has(> *):hover {\n\t\tbackground-color: var(--amll-lp-hover-bg-color, #fff1);\n\t\t/* box-shadow: 0 0 0 4px var(--amll-lp-hover-bg-color, #fff1); */\n\t}\n\n\t&:has(> *):active {\n\t\tbackground-color: var(--amll-lp-hover-bg-color, #ffffff05);\n\t\t/* box-shadow: 0 0 0 var(--amll-lp-hover-bg-color, #fff1); */\n\t}\n}\n\n.lyricBgLine {\n\topacity: 0;\n\tfont-size: max(calc(1em * var(--amll-lp-bg-line-scale, 0.7)), 10px);\n\ttransition:\n\t\topacity 0.25s,\n\t\tscale 0.5s,\n\t\tfilter 0.2s,\n\t\tbackground-color 0.25s,\n\t\tbox-shadow 0.25s;\n\t/* 因为字体大小缩小了,故内边距要和主行字体大小统一,行边距计算公式为 100% / font-size 转 em 单位 */\n\tpadding: 1vh\n\t\tcalc(var(--amll-lp-line-padding-x, 1em) / var(--amll-lp-bg-line-scale, 0.7));\n\n\t&.active {\n\t\ttransition:\n\t\t\topacity 0.5s 0.25s,\n\t\t\tscale 1.5s cubic-bezier(0, 1, 0, 1) 0.25s,\n\t\t\tfilter 0.2s,\n\t\t\tbackground-color 0.25s,\n\t\t\tbox-shadow 0.25s;\n\t\topacity: 0.4;\n\t}\n}\n\n:global(.amll-lyric-player) {\n\t&:hover .lyricLine {\n\t\tfilter: unset !important;\n\t}\n\n\t&.hasDuetLine {\n\t\t.lyricLine:not(.lyricDuetLine) {\n\t\t\tpadding-right: 15%;\n\t\t}\n\t\t.lyricDuetLine {\n\t\t\tpadding-left: 15%;\n\t\t}\n\t}\n}\n\n.lyricDuetLine {\n\ttext-align: right;\n\ttransform-origin: right;\n}\n\n.lyricMainLine {\n\ttransition: opacity 0.3s 0.1s;\n\tcontain: content paint;\n\n\tspan {\n\t\tdisplay: inline-block;\n\t\twhite-space: pre;\n\t}\n\n\t.romanWord {\n\t\tfont-size: 0.5em;\n\t\tline-height: 1em;\n\t\tdisplay: flex;\n\t}\n\n\t.rubyWord {\n\t\tfont-size: 0.5em;\n\t\tline-height: 1em;\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\tmin-height: 1em;\n\t}\n\n\t.wordWithRuby {\n\t\tdisplay: inline-flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t}\n\n\t.wordBody {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t}\n}\n\n.lyricSubLine {\n\tfont-size: max(0.5em, 10px);\n\tline-height: 1.5em;\n\ttransition: opacity 0.2s 0.25s;\n\topacity: 0.3;\n}\n\n.interludeDots {\n\theight: clamp(0.5em, 1vh, 3em);\n\ttransition: opacity 0.25s;\n\ttransform-origin: center;\n\twidth: fit-content;\n\tpadding: 2.5% 0.75em;\n\tdisplay: flex;\n\tgap: 0.25em;\n\tleft: 0;\n\topacity: 0;\n\n\t&.enabled {\n\t\topacity: 1;\n\t}\n\n\t& > * {\n\t\twidth: clamp(0.5em, 1vh, 3em);\n\t\theight: clamp(0.5em, 1vh, 3em);\n\t\tdisplay: inline-block;\n\t\tborder-radius: 50%;\n\t\taspect-ratio: 1 / 1;\n\t\tbackground-color: var(--amll-lp-color, white);\n\t\tmargin-right: 4px;\n\t}\n\n\t&.duet {\n\t\tright: 0;\n\t\ttransform-origin: center;\n\t}\n}\n\n@supports (mix-blend-mode: plus-lighter) {\n\t.lyricSubLine {\n\t\topacity: 0.3;\n\t}\n}\n\n.tmpDisableTransition {\n\ttransition: none !important;\n}\n","// 一个异步互斥锁,用于控制并发\n\nexport function mutexifyFunction<\n\tF extends (...args: Args) => Promise<Result>,\n\tArgs extends any[],\n\tResult,\n>(func: F): F {\n\tconst awaitingTasks: {\n\t\tresolve: (value: Result) => void;\n\t\treject: (reason: any) => void;\n\t\targs: Args;\n\t}[] = [];\n\tfunction processNextTask() {\n\t\tconst task = awaitingTasks[0];\n\t\tif (!task) return;\n\t\tfunc(...task.args)\n\t\t\t.then((value) => {\n\t\t\t\ttask.resolve(value);\n\t\t\t})\n\t\t\t.catch((reason) => {\n\t\t\t\ttask.reject(reason);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tawaitingTasks.shift();\n\t\t\t\tif (awaitingTasks.length > 0) {\n\t\t\t\t\tprocessNextTask();\n\t\t\t\t}\n\t\t\t});\n\t}\n\treturn ((...args: Args) => {\n\t\treturn new Promise<Result>((resolve, reject) => {\n\t\t\tawaitingTasks.push({ resolve, reject, args });\n\t\t\tif (awaitingTasks.length === 1) {\n\t\t\t\tprocessNextTask();\n\t\t\t}\n\t\t});\n\t}) as F;\n}\n\nexport default mutexifyFunction;\n","import bezier from \"bezier-easing\";\nimport type { LyricLine, LyricWord } from \"../../interfaces.ts\";\nimport { chunkAndSplitLyricWords } from \"../../utils/lyric-split-words.ts\";\nimport {\n\tcreateMatrix4,\n\tmatrix4ToCSS,\n\tscaleMatrix4,\n} from \"../../utils/matrix.ts\";\nimport { mutexifyFunction } from \"../../utils/mutex.ts\";\nimport { measure, mutate } from \"../../utils/schedule.ts\";\nimport { LyricLineBase } from \"../base.ts\";\nimport styles from \"./index.module.css\";\nimport type { DomSlimLyricPlayer } from \"./index.ts\";\n\ninterface RealWord extends LyricWord {\n\tmainElement: HTMLSpanElement;\n\tsubElements: HTMLSpanElement[];\n\telementAnimations: Animation[];\n\tmaskAnimations: Animation[];\n\twidth: number;\n\theight: number;\n\tpadding: number;\n\tshouldEmphasize: boolean;\n}\n\nconst ANIMATION_FRAME_QUANTITY = 32;\n\nconst norNum = (min: number, max: number) => (x: number) =>\n\tMath.min(1, Math.max(0, (x - min) / (max - min)));\nconst EMP_EASING_MID = 0.5;\nconst beginNum = norNum(0, EMP_EASING_MID);\nconst endNum = norNum(EMP_EASING_MID, 1);\n\nconst bezIn = bezier(0.2, 0.4, 0.58, 1.0);\nconst bezOut = bezier(0.3, 0.0, 0.58, 1.0);\n\nconst makeEmpEasing = (mid: number) => {\n\treturn (x: number) => (x < mid ? bezIn(beginNum(x)) : 1 - bezOut(endNum(x)));\n};\n\nfunction generateFadeGradient(\n\twidth: number,\n\tpadding = 0,\n\tbright = \"rgba(0,0,0,var(--bright-mask-alpha, 1.0))\",\n\tdark = \"rgba(0,0,0,var(--dark-mask-alpha, 1.0))\",\n): [string, number] {\n\tconst totalAspect = 2 + width + padding;\n\tconst widthInTotal = width / totalAspect;\n\tconst leftPos = (1 - widthInTotal) / 2;\n\treturn [\n\t\t`linear-gradient(to right,${bright} ${leftPos * 100}%,${dark} ${\n\t\t\t(leftPos + widthInTotal) * 100\n\t\t}%)`,\n\t\ttotalAspect,\n\t];\n}\n\nexport class RawLyricLineMouseEvent extends MouseEvent {\n\tconstructor(\n\t\tpublic readonly line: LyricLineEl,\n\t\tevent: MouseEvent,\n\t) {\n\t\tsuper(event.type, event);\n\t}\n}\n\nfunction getScaleFromTransform(transform: string): number {\n\tconst match = transform.match(/matrix\\(([^)]+)\\)/);\n\tif (match) {\n\t\tconst values = match[1].split(\", \");\n\t\tconst scaleX = Number.parseFloat(values[0]);\n\t\tconst scaleY = Number.parseFloat(values[3]);\n\t\treturn (scaleX + scaleY) / 2; // Average of scaleX and scaleY\n\t}\n\treturn 1; // Default scale value if not found\n}\n\ntype MouseEventMap = {\n\t[evt in keyof HTMLElementEventMap]: HTMLElementEventMap[evt] extends MouseEvent\n\t\t? evt\n\t\t: never;\n};\ntype MouseEventTypes = MouseEventMap[keyof MouseEventMap];\ntype MouseEventListener = (\n\tthis: LyricLineEl,\n\tev: RawLyricLineMouseEvent,\n) => void;\n\nexport class LyricLineEl extends LyricLineBase {\n\tprivate element: HTMLElement = document.createElement(\"div\");\n\tprivate splittedWords: RealWord[] = [];\n\t// 由 LyricPlayer 来设置\n\tlineSize: number[] = [0, 0];\n\n\tconstructor(\n\t\tprivate lyricPlayer: DomSlimLyricPlayer,\n\t\tprivate lyricLine: LyricLine = {\n\t\t\twords: [],\n\t\t\ttranslatedLyric: \"\",\n\t\t\tromanLyric: \"\",\n\t\t\tstartTime: 0,\n\t\t\tendTime: 0,\n\t\t\tisBG: false,\n\t\t\tisDuet: false,\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.element.setAttribute(\"class\", styles.lyricLine);\n\t\tif (this.lyricLine.isBG) {\n\t\t\tthis.element.classList.add(styles.lyricBgLine);\n\t\t}\n\t\tif (this.lyricLine.isDuet) {\n\t\t\tthis.element.classList.add(styles.lyricDuetLine);\n\t\t}\n\t\tthis.element.appendChild(document.createElement(\"div\")); // 歌词行\n\t\tthis.element.appendChild(document.createElement(\"div\")); // 翻译行\n\t\tthis.element.appendChild(document.createElement(\"div\")); // 音译行\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tconst trans = this.element.children[1] as HTMLDivElement;\n\t\tconst roman = this.element.children[2] as HTMLDivElement;\n\t\tmain.setAttribute(\"class\", styles.lyricMainLine);\n\t\ttrans.setAttribute(\"class\", styles.lyricSubLine);\n\t\troman.setAttribute(\"class\", styles.lyricSubLine);\n\t\tthis.rebuildElement();\n\t\tthis.rebuildStyle();\n\t\tthis.markMaskImageDirty(\"Initial construction\");\n\t}\n\tprivate listenersMap = new Map<string, Set<MouseEventListener>>();\n\tprivate readonly onMouseEvent = (e: MouseEvent) => {\n\t\tconst wrapped = new RawLyricLineMouseEvent(this, e);\n\t\tfor (const listener of this.listenersMap.get(e.type) ?? []) {\n\t\t\tlistener.call(this, wrapped);\n\t\t}\n\t\tif (!this.dispatchEvent(wrapped) || wrapped.defaultPrevented) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\t};\n\n\taddMouseEventListener(\n\t\ttype: MouseEventTypes,\n\t\tcallback: MouseEventListener | null,\n\t\toptions?: boolean | AddEventListenerOptions | undefined,\n\t): void {\n\t\tif (callback) {\n\t\t\tconst listeners = this.listenersMap.get(type) ?? new Set();\n\t\t\tif (listeners.size === 0)\n\t\t\t\tthis.element.addEventListener(type, this.onMouseEvent, options);\n\t\t\tlisteners.add(callback);\n\t\t\tthis.listenersMap.set(type, listeners);\n\t\t}\n\t}\n\n\tremoveMouseEventListener(\n\t\ttype: MouseEventTypes,\n\t\tcallback: MouseEventListener | null,\n\t\toptions?: boolean | EventListenerOptions | undefined,\n\t): void {\n\t\tif (callback) {\n\t\t\tconst listeners = this.listenersMap.get(type);\n\t\t\tif (listeners) {\n\t\t\t\tlisteners.delete(callback);\n\t\t\t\tif (listeners.size === 0)\n\t\t\t\t\tthis.element.removeEventListener(type, this.onMouseEvent, options);\n\t\t\t}\n\t\t}\n\t}\n\n\tareWordsOnSameLine(word1: RealWord, word2: RealWord): boolean {\n\t\tif (word1?.mainElement && word2?.mainElement) {\n\t\t\tconst word1el = word1.mainElement;\n\t\t\tconst word2el = word2.mainElement;\n\n\t\t\tconst rect1 = word1el.getBoundingClientRect();\n\t\t\tconst rect2 = word2el.getBoundingClientRect();\n\n\t\t\t// 检查两个单词的顶部距离是否相等(或者差值很小)\n\t\t\tconst topDifference = Math.abs(rect1.top - rect2.top);\n\n\t\t\t// 如果顶部距离相差很小,可以认为它们在同一行上\n\t\t\treturn topDifference < 10;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate isEnabled = false;\n\tasync enable(\n\t\tmaskAnimationTime: number = this.lyricLine.startTime,\n\t): Promise<void> {\n\t\tthis.isEnabled = true;\n\t\tthis.element.classList.add(styles.active);\n\t\tawait this.waitMaskImageUpdated();\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\ta.currentTime = 0;\n\t\t\t\ta.playbackRate = 1;\n\t\t\t\ta.play();\n\t\t\t}\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\ta.currentTime = Math.min(\n\t\t\t\t\tthis.totalDuration,\n\t\t\t\t\tMath.max(0, maskAnimationTime - this.lyricLine.startTime),\n\t\t\t\t);\n\t\t\t\ta.playbackRate = 1;\n\t\t\t\ta.play();\n\t\t\t}\n\t\t}\n\t\tmain.classList.add(styles.active);\n\t}\n\tdisable(): void {\n\t\tthis.isEnabled = false;\n\t\tthis.element.classList.remove(styles.active);\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\tif (\n\t\t\t\t\ta.id === \"float-word\" ||\n\t\t\t\t\ta.id.includes(\"emphasize-word-float-only\")\n\t\t\t\t) {\n\t\t\t\t\ta.playbackRate = -1;\n\t\t\t\t\ta.play();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tmain.classList.remove(styles.active);\n\t}\n\tprivate lastWord?: RealWord;\n\tasync resume(): Promise<void> {\n\t\tawait this.waitMaskImageUpdated();\n\t\tif (!this.isEnabled) return;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\tif (\n\t\t\t\t\t!this.lastWord ||\n\t\t\t\t\tthis.splittedWords.indexOf(this.lastWord) <\n\t\t\t\t\t\tthis.splittedWords.indexOf(word)\n\t\t\t\t) {\n\t\t\t\t\ta.play();\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\tif (\n\t\t\t\t\t!this.lastWord ||\n\t\t\t\t\tthis.splittedWords.indexOf(this.lastWord) <\n\t\t\t\t\t\tthis.splittedWords.indexOf(word)\n\t\t\t\t) {\n\t\t\t\t\ta.play();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tasync pause(): Promise<void> {\n\t\tawait this.waitMaskImageUpdated();\n\t\tif (!this.isEnabled) return;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.elementAnimations) {\n\t\t\t\ta.pause();\n\t\t\t}\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\ta.pause();\n\t\t\t}\n\t\t}\n\t}\n\tsetMaskAnimationState(maskAnimationTime = 0): void {\n\t\tconst t = maskAnimationTime - this.lyricLine.startTime;\n\t\tfor (const word of this.splittedWords) {\n\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\ta.currentTime = Math.min(this.totalDuration, Math.max(0, t));\n\t\t\t\ta.playbackRate = 1;\n\t\t\t\tif (t >= 0 && t < this.totalDuration) a.play();\n\t\t\t\telse a.pause();\n\t\t\t}\n\t\t}\n\t}\n\tprivate measureLockMark = false;\n\tprivate measureLock = mutexifyFunction(\n\t\tasync (callback: () => Promise<void>): Promise<void> => {\n\t\t\tif (this.measureLockMark) return;\n\t\t\tthis.measureLockMark = true;\n\t\t\t// if (this._hide) {\n\t\t\t// \tawait mutate(() => {\n\t\t\t// \t\tthis._prevParentEl.appendChild(this.element);\n\t\t\t// \t\tthis.element.style.display = \"\";\n\t\t\t// \t\tthis.element.style.visibility = \"hidden\";\n\t\t\t// \t});\n\t\t\t// }\n\t\t\tawait callback();\n\t\t\t// if (this._hide) {\n\t\t\t// \tawait mutate(() => {\n\t\t\t// \t\tthis._prevParentEl.removeChild(this.element);\n\t\t\t// \t\tthis.element.style.display = \"none\";\n\t\t\t// \t\tthis.element.style.visibility = \"\";\n\t\t\t// \t});\n\t\t\t// }\n\t\t\tthis.measureLockMark = false;\n\t\t},\n\t);\n\n\tgetLine(): LyricLine {\n\t\treturn this.lyricLine;\n\t}\n\tshow(): void {\n\t\t// this._hide = false;\n\t\t// if (!this.measureLockMark && !this.element.parentElement) {\n\t\t// \tthis._prevParentEl.appendChild(this.element);\n\t\t// }\n\t\tthis.rebuildStyle();\n\t}\n\thide(): void {\n\t\t// this._hide = true;\n\t\t// if (!this.measureLockMark && this.element.parentElement) {\n\t\t// \tthis._prevParentEl.removeChild(this.element);\n\t\t// }\n\t}\n\tprivate rebuildStyle() {\n\t\t// let style = \"\";\n\t\t// if (!this.lyricPlayer.getEnableSpring() && this.isInSight) {\n\t\t// \tstyle += `transition-delay:${this.delay}ms;`;\n\t\t// }\n\t\t// style += `filter:blur(${Math.min(32, this.blur)}px);`;\n\t\t// if (style !== this.lastStyle) {\n\t\t// \tthis.lastStyle = style;\n\t\t// \tthis.element.setAttribute(\"style\", style);\n\t\t// }\n\t}\n\n\tprivate getRubySegments(word: LyricWord) {\n\t\treturn (word.ruby ?? []).filter(\n\t\t\t(ruby) => (ruby?.word?.trim().length ?? 0) > 0,\n\t\t);\n\t}\n\n\tprivate buildWordElement(\n\t\tword: LyricWord,\n\t\tshouldEmphasize: boolean,\n\t\thasRubyLine: boolean,\n\t\thasRomanLine: boolean,\n\t\tdisplayWord: string,\n\t) {\n\t\tconst mainWordEl = document.createElement(\"span\");\n\t\tconst subElements: HTMLSpanElement[] = [];\n\t\tconst romanWord = word.romanWord?.trim() ?? \"\";\n\t\tlet wordContainer: HTMLElement = mainWordEl;\n\t\tif (hasRubyLine || hasRomanLine) {\n\t\t\twordContainer = document.createElement(\"div\");\n\t\t\tmainWordEl.appendChild(wordContainer);\n\t\t}\n\t\tif (hasRubyLine) {\n\t\t\tconst rubyWordEl = document.createElement(\"div\");\n\t\t\tconst rubySegments = this.getRubySegments(word);\n\t\t\tfor (const ruby of rubySegments) {\n\t\t\t\tconst rubyPartEl = document.createElement(\"span\");\n\t\t\t\trubyPartEl.innerText = ruby.word;\n\t\t\t\trubyPartEl.dataset.startTime = String(ruby.startTime);\n\t\t\t\trubyPartEl.dataset.endTime = String(ruby.endTime);\n\t\t\t\trubyWordEl.appendChild(rubyPartEl);\n\t\t\t}\n\t\t\trubyWordEl.classList.add(styles.rubyWord);\n\t\t\tmainWordEl.classList.add(styles.wordWithRuby);\n\t\t\twordContainer.classList.add(styles.wordBody);\n\t\t\tmainWordEl.insertBefore(rubyWordEl, wordContainer);\n\t\t}\n\n\t\tif (shouldEmphasize) {\n\t\t\tmainWordEl.classList.add(styles.emphasize);\n\t\t\tfor (const char of displayWord.trim()) {\n\t\t\t\tconst charEl = document.createElement(\"span\");\n\t\t\t\tcharEl.innerText = char;\n\t\t\t\tsubElements.push(charEl);\n\t\t\t\twordContainer.appendChild(charEl);\n\t\t\t}\n\t\t} else if (hasRomanLine) {\n\t\t\tconst wordEl = document.createElement(\"div\");\n\t\t\twordEl.innerText = displayWord;\n\t\t\twordContainer.appendChild(wordEl);\n\t\t} else {\n\t\t\tmainWordEl.innerText = displayWord;\n\t\t}\n\n\t\tif (hasRomanLine) {\n\t\t\tconst romanWordEl = document.createElement(\"div\");\n\t\t\tromanWordEl.innerText = romanWord.length > 0 ? romanWord : \"\\u00A0\";\n\t\t\tromanWordEl.classList.add(styles.romanWord);\n\t\t\twordContainer.appendChild(romanWordEl);\n\t\t}\n\n\t\treturn { mainWordEl, subElements };\n\t}\n\toverride rebuildElement(): void {\n\t\tthis.disposeElements();\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\tconst trans = this.element.children[1] as HTMLDivElement;\n\t\tconst roman = this.element.children[2] as HTMLDivElement;\n\t\t// 如果是非动态歌词,那么就不需要分词了\n\t\tif (this.lyricPlayer._getIsNonDynamic()) {\n\t\t\tmain.innerText = this.lyricLine.words\n\t\t\t\t.map((w) => this.lyricPlayer.processObsceneWord(w))\n\t\t\t\t.join(\"\");\n\t\t\ttrans.innerText = this.lyricLine.translatedLyric;\n\t\t\troman.innerText = this.lyricLine.romanLyric;\n\t\t\treturn;\n\t\t}\n\t\tconst chunkedWords = chunkAndSplitLyricWords(this.lyricLine.words);\n\t\tconst hasRubyLine = this.lyricLine.words.some(\n\t\t\t(word) => (word.ruby?.length ?? 0) > 0,\n\t\t);\n\t\tconst hasRomanLine = this.lyricLine.words.some(\n\t\t\t(word) => (word.romanWord?.trim().length ?? 0) > 0,\n\t\t);\n\t\tmain.innerHTML = \"\";\n\t\tfor (const chunk of chunkedWords) {\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\t// 多个没有空格的单词组合成的一个单词数组\n\t\t\t\tif (chunk.length === 0) continue;\n\t\t\t\tconst merged = chunk.reduce(\n\t\t\t\t\t(a, b) => {\n\t\t\t\t\t\ta.endTime = Math.max(a.endTime, b.endTime);\n\t\t\t\t\t\ta.startTime = Math.min(a.startTime, b.startTime);\n\t\t\t\t\t\ta.word += b.word;\n\t\t\t\t\t\treturn a;\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tword: \"\",\n\t\t\t\t\t\tromanWord: \"\",\n\t\t\t\t\t\tstartTime: Number.POSITIVE_INFINITY,\n\t\t\t\t\t\tendTime: Number.NEGATIVE_INFINITY,\n\t\t\t\t\t\twordType: \"normal\",\n\t\t\t\t\t\tobscene: false,\n\t\t\t\t\t} as LyricWord,\n\t\t\t\t);\n\t\t\t\tconst emp = chunk\n\t\t\t\t\t.map((word) => LyricLineBase.shouldEmphasize(word))\n\t\t\t\t\t.reduce((a, b) => a || b, LyricLineBase.shouldEmphasize(merged));\n\t\t\t\tconst wrapperWordEl = document.createElement(\"span\");\n\t\t\t\twrapperWordEl.classList.add(styles.emphasizeWrapper);\n\t\t\t\tconst characterElements: HTMLElement[] = [];\n\t\t\t\tfor (const word of chunk) {\n\t\t\t\t\tconst { mainWordEl, subElements } = this.buildWordElement(\n\t\t\t\t\t\tword,\n\t\t\t\t\t\temp,\n\t\t\t\t\t\thasRubyLine,\n\t\t\t\t\t\thasRomanLine,\n\t\t\t\t\t\tthis.lyricPlayer.processObsceneWord(word),\n\t\t\t\t\t);\n\t\t\t\t\tif (emp) {\n\t\t\t\t\t\tcharacterElements.push(...subElements);\n\t\t\t\t\t}\n\t\t\t\t\tthis.splittedWords.push({\n\t\t\t\t\t\t...word,\n\t\t\t\t\t\tmainElement: mainWordEl,\n\t\t\t\t\t\tsubElements: subElements,\n\t\t\t\t\t\t// elementAnimations: [this.initFloatAnimation(word, mainWordEl)],\n\t\t\t\t\t\telementAnimations: [], // this.initFloatAnimation(word, mainWordEl)\n\t\t\t\t\t\tmaskAnimations: [],\n\t\t\t\t\t\twidth: 0,\n\t\t\t\t\t\theight: 0,\n\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\tshouldEmphasize: emp,\n\t\t\t\t\t});\n\t\t\t\t\twrapperWordEl.appendChild(mainWordEl);\n\t\t\t\t}\n\t\t\t\tif (emp) {\n\t\t\t\t\tthis.splittedWords[\n\t\t\t\t\t\tthis.splittedWords.length - 1\n\t\t\t\t\t].elementAnimations.push(\n\t\t\t\t\t\t...this.initEmphasizeAnimation(\n\t\t\t\t\t\t\tmerged,\n\t\t\t\t\t\t\tcharacterElements,\n\t\t\t\t\t\t\tmerged.endTime - merged.startTime,\n\t\t\t\t\t\t\tmerged.startTime - this.lyricLine.startTime,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (merged.word.trimStart() !== merged.word) {\n\t\t\t\t\tmain.appendChild(document.createTextNode(\" \"));\n\t\t\t\t}\n\t\t\t\tmain.appendChild(wrapperWordEl);\n\t\t\t\tif (\n\t\t\t\t\tmerged.word.trimEnd() !== merged.word &&\n\t\t\t\t\tLyricLineBase.shouldEmphasize(merged)\n\t\t\t\t) {\n\t\t\t\t\tmain.appendChild(document.createTextNode(\" \"));\n\t\t\t\t}\n\t\t\t} else if (chunk.word.trim().length === 0) {\n\t\t\t\t// 纯空格\n\t\t\t\tmain.appendChild(document.createTextNode(\" \"));\n\t\t\t} else {\n\t\t\t\t// 单个单词\n\t\t\t\tconst emp = LyricLineBase.shouldEmphasize(chunk);\n\t\t\t\tconst { mainWordEl, subElements } = this.buildWordElement(\n\t\t\t\t\tchunk,\n\t\t\t\t\temp,\n\t\t\t\t\thasRubyLine,\n\t\t\t\t\thasRomanLine,\n\t\t\t\t\tthis.lyricPlayer.processObsceneWord(chunk).trim(),\n\t\t\t\t);\n\t\t\t\tconst realWord: RealWord = {\n\t\t\t\t\t...chunk,\n\t\t\t\t\tmainElement: mainWordEl,\n\t\t\t\t\tsubElements: subElements,\n\t\t\t\t\t// elementAnimations: [this.initFloatAnimation(chunk, mainWordEl)],\n\t\t\t\t\telementAnimations: [], // this.initFloatAnimation(chunk, mainWordEl)\n\t\t\t\t\tmaskAnimations: [],\n\t\t\t\t\twidth: 0,\n\t\t\t\t\theight: 0,\n\t\t\t\t\tpadding: 0,\n\t\t\t\t\tshouldEmphasize: emp,\n\t\t\t\t};\n\t\t\t\tif (emp) {\n\t\t\t\t\tconst duration = Math.abs(realWord.endTime - realWord.startTime);\n\t\t\t\t\trealWord.elementAnimations.push(\n\t\t\t\t\t\t...this.initEmphasizeAnimation(\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tsubElements,\n\t\t\t\t\t\t\tduration,\n\t\t\t\t\t\t\trealWord.startTime - this.lyricLine.startTime,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (chunk.word.trimStart() !== chunk.word) {\n\t\t\t\t\tmain.appendChild(document.createTextNode(\" \"));\n\t\t\t\t}\n\t\t\t\tmain.appendChild(mainWordEl);\n\t\t\t\tif (chunk.word.trimEnd() !== chunk.word) {\n\t\t\t\t\tmain.appendChild(document.createTextNode(\" \"));\n\t\t\t\t}\n\t\t\t\tthis.splittedWords.push(realWord);\n\t\t\t}\n\t\t}\n\t\ttrans.innerText = this.lyricLine.translatedLyric;\n\t\troman.innerText = this.lyricLine.romanLyric;\n\t}\n\t// 按照原 Apple Music 参考,强调效果只应用缩放、轻微左右位移和辉光效果,原主要的悬浮位移效果不变\n\t// 为了避免产生锯齿抖动感,使用 matrix3d 来实现缩放和位移\n\tprivate initEmphasizeAnimation(\n\t\tword: LyricWord,\n\t\tcharacterElements: HTMLElement[],\n\t\tduration: number,\n\t\tdelay: number,\n\t): Animation[] {\n\t\tconst de = Math.max(0, delay);\n\t\tlet du = Math.max(1000, duration);\n\n\t\tlet result: Animation[] = [];\n\n\t\tlet amount = du / 2000;\n\t\tamount = amount > 1 ? Math.sqrt(amount) : amount ** 3;\n\t\tlet blur = du / 3000;\n\t\tblur = blur > 1 ? Math.sqrt(blur) : blur ** 3;\n\t\tamount *= 0.6;\n\t\tblur *= 0.5;\n\t\tif (\n\t\t\tthis.lyricLine.words.length > 0 &&\n\t\t\tword.word.includes(\n\t\t\t\tthis.lyricLine.words[this.lyricLine.words.length - 1].word,\n\t\t\t)\n\t\t) {\n\t\t\tamount *= 1.6;\n\t\t\tblur *= 1.5;\n\t\t\tdu *= 1.2;\n\t\t}\n\t\tamount = Math.min(1.2, amount);\n\t\tblur = Math.min(0.8, blur);\n\n\t\tconst animateDu = Number.isFinite(du) ? du : 0;\n\t\tconst empEasing = makeEmpEasing(EMP_EASING_MID);\n\n\t\tresult = characterElements.flatMap((el, i, arr) => {\n\t\t\tconst wordDe = de + (du / 2.5 / arr.length) * i;\n\t\t\tconst result: Animation[] = [];\n\n\t\t\tconst frames: Keyframe[] = new Array(ANIMATION_FRAME_QUANTITY)\n\t\t\t\t.fill(0)\n\t\t\t\t.map((_, j) => {\n\t\t\t\t\tconst x = (j + 1) / ANIMATION_FRAME_QUANTITY;\n\t\t\t\t\tconst transX = empEasing(x);\n\t\t\t\t\tconst glowLevel = empEasing(x) * blur;\n\n\t\t\t\t\tconst mat = scaleMatrix4(createMatrix4(), 1 + transX * 0.1 * amount);\n\t\t\t\t\tconst offsetX = -transX * 0.03 * amount * (arr.length / 2 - i);\n\t\t\t\t\tconst offsetY = -transX * 0.025 * amount;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\toffset: x,\n\t\t\t\t\t\ttransform: `${matrix4ToCSS(\n\t\t\t\t\t\t\tmat,\n\t\t\t\t\t\t\t4,\n\t\t\t\t\t\t)} translate(${offsetX}em, ${offsetY}em)`,\n\t\t\t\t\t\ttextShadow: `0 0 ${Math.min(\n\t\t\t\t\t\t\t0.3,\n\t\t\t\t\t\t\tblur * 0.3,\n\t\t\t\t\t\t)}em rgba(255, 255, 255, ${glowLevel})`,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\tconst glow = el.animate(frames, {\n\t\t\t\tduration: animateDu,\n\t\t\t\tdelay: Number.isFinite(wordDe) ? wordDe : 0,\n\t\t\t\tid: `emphasize-word-${el.innerText}-${i}`,\n\t\t\t\titerations: 1,\n\t\t\t\tcomposite: \"replace\",\n\t\t\t\tfill: \"both\",\n\t\t\t});\n\t\t\tglow.onfinish = () => {\n\t\t\t\tglow.pause();\n\t\t\t};\n\t\t\tglow.pause();\n\t\t\tresult.push(glow);\n\n\t\t\tconst floatFrame: Keyframe[] = new Array(ANIMATION_FRAME_QUANTITY)\n\t\t\t\t.fill(0)\n\t\t\t\t.map((_, j) => {\n\t\t\t\t\tconst x = (j + 1) / ANIMATION_FRAME_QUANTITY;\n\t\t\t\t\tlet y = Math.sin(x * Math.PI);\n\t\t\t\t\t// y = x < 0.5 ? y : Math.max(y, 1.0);\n\t\t\t\t\tif (this.lyricLine.isBG) {\n\t\t\t\t\t\ty *= 2;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\toffset: x,\n\t\t\t\t\t\ttransform: `translateY(${-y * 0.05}em)`,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\tconst float = el.animate(floatFrame, {\n\t\t\t\tduration: animateDu * 1.4,\n\t\t\t\tdelay: Number.isFinite(wordDe) ? wordDe - 400 : 0,\n\t\t\t\tid: \"emphasize-word-float\",\n\t\t\t\titerations: 1,\n\t\t\t\tcomposite: \"add\",\n\t\t\t\tfill: \"both\",\n\t\t\t});\n\t\t\tfloat.onfinish = () => {\n\t\t\t\tfloat.pause();\n\t\t\t};\n\t\t\tfloat.pause();\n\t\t\tresult.push(float);\n\n\t\t\treturn result;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tprivate get totalDuration() {\n\t\treturn this.lyricLine.endTime - this.lyricLine.startTime;\n\t}\n\tprivate maskImageDirty = false;\n\tprivate markImageDirtyPromiseResolve: Set<() => void> = new Set();\n\tprivate markImageDirtyPromise: Promise<void> = new Promise((resolve) => {\n\t\tthis.markImageDirtyPromiseResolve.add(resolve);\n\t});\n\tmarkMaskImageDirty(_debugReason = \"\"): Promise<void> {\n\t\tthis.maskImageDirty = true;\n\t\tif (!this.element.classList.contains(styles.dirty))\n\t\t\tthis.element.classList.add(styles.dirty);\n\t\t// if (import.meta.env.DEV) {\n\t\t// \tconsole.log(\"Mark mask image dirty: \", _debugReason);\n\t\t// }\n\t\tconst newPromise = Promise.all([\n\t\t\tthis.markImageDirtyPromise,\n\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\tthis.markImageDirtyPromiseResolve.add(resolve);\n\t\t\t}),\n\t\t]).then(() => {});\n\t\tthis.markImageDirtyPromise = newPromise;\n\t\treturn newPromise;\n\t}\n\twaitMaskImageUpdated(): Promise<void> {\n\t\treturn this.markImageDirtyPromise;\n\t}\n\tasync updateMaskImage(): Promise<void> {\n\t\tif (\n\t\t\t!this.element.checkVisibility({\n\t\t\t\tcontentVisibilityAuto: true,\n\t\t\t})\n\t\t)\n\t\t\treturn;\n\t\tthis.maskImageDirty = false;\n\t\tawait this.measureLock(async () => {\n\t\t\tawait Promise.all(\n\t\t\t\tthis.splittedWords.map(async (word) => {\n\t\t\t\t\tconst el = word.mainElement;\n\t\t\t\t\tif (el) {\n\t\t\t\t\t\tawait measure(() => {\n\t\t\t\t\t\t\tword.padding = Number.parseFloat(\n\t\t\t\t\t\t\t\tgetComputedStyle(el).paddingLeft,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tword.width = el.clientWidth - word.padding * 2;\n\t\t\t\t\t\t\tword.height = el.clientHeight - word.padding * 2;\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tword.width = 0;\n\t\t\t\t\t\tword.height = 0;\n\t\t\t\t\t\tword.padding = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (word.width * word.height === 0) {\n\t\t\t\t\t\tconsole.warn(\"Word size is zero\");\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tawait mutate(() => {\n\t\t\t\tif (this.lyricPlayer.supportMaskImage) {\n\t\t\t\t\tthis.generateWebAnimationBasedMaskImage();\n\t\t\t\t} else {\n\t\t\t\t\tthis.generateCalcBasedMaskImage();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tfor (const resolve of this.markImageDirtyPromiseResolve) {\n\t\t\tresolve();\n\t\t\tthis.markImageDirtyPromiseResolve.delete(resolve);\n\t\t}\n\t\tawait mutate(() => {\n\t\t\tthis.element.classList.remove(styles.dirty);\n\t\t});\n\t}\n\tprivate generateCalcBasedMaskImage() {\n\t\tfor (const word of this.splittedWords) {\n\t\t\tconst wordEl = word.mainElement;\n\t\t\tif (wordEl) {\n\t\t\t\tword.width = wordEl.clientWidth;\n\t\t\t\tword.height = wordEl.clientHeight;\n\t\t\t\tconst fadeWidth = word.height * this.lyricPlayer.getWordFadeWidth();\n\t\t\t\tconst [maskImage, totalAspect] = generateFadeGradient(\n\t\t\t\t\tfadeWidth / word.width,\n\t\t\t\t);\n\t\t\t\tconst totalAspectStr = `${totalAspect * 100}% 100%`;\n\t\t\t\tif (this.lyricPlayer.supportMaskImage) {\n\t\t\t\t\twordEl.style.maskImage = maskImage;\n\t\t\t\t\twordEl.style.maskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.maskOrigin = \"left\";\n\t\t\t\t\twordEl.style.maskSize = totalAspectStr;\n\t\t\t\t} else {\n\t\t\t\t\twordEl.style.webkitMaskImage = maskImage;\n\t\t\t\t\twordEl.style.webkitMaskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.webkitMaskOrigin = \"left\";\n\t\t\t\t\twordEl.style.webkitMaskSize = totalAspectStr;\n\t\t\t\t}\n\t\t\t\tconst w = word.width + fadeWidth;\n\t\t\t\tconst maskPos = `clamp(${-w}px,calc(${-w}px + (var(--amll-player-time) - ${\n\t\t\t\t\tword.startTime\n\t\t\t\t})*${\n\t\t\t\t\tw / Math.abs(word.endTime - word.startTime)\n\t\t\t\t}px),0px) 0px, left top`;\n\t\t\t\twordEl.style.maskPosition = maskPos;\n\t\t\t\twordEl.style.webkitMaskPosition = maskPos;\n\t\t\t}\n\t\t}\n\t}\n\tprivate generateWebAnimationBasedMaskImage() {\n\t\t// 因为歌词行有可能比行内单词的结束时间早,有可能导致过渡动画提早停止出现瑕疵\n\t\t// 所以要以单词的结束时间为准\n\t\tconst totalFadeDuration =\n\t\t\tMath.max(\n\t\t\t\tthis.splittedWords.reduce((pv, w) => Math.max(w.endTime, pv), 0),\n\t\t\t\tthis.lyricLine.endTime,\n\t\t\t) - this.lyricLine.startTime;\n\t\tthis.splittedWords.forEach((word, i) => {\n\t\t\tconst wordEl = word.mainElement;\n\t\t\tif (wordEl) {\n\t\t\t\tconst fadeWidth = word.height * this.lyricPlayer.getWordFadeWidth();\n\t\t\t\tconst [maskImage, totalAspect] = generateFadeGradient(\n\t\t\t\t\tfadeWidth / (word.width + word.padding * 2),\n\t\t\t\t);\n\t\t\t\tconst totalAspectStr = `${totalAspect * 100}% 100%`;\n\t\t\t\tif (this.lyricPlayer.supportMaskImage) {\n\t\t\t\t\twordEl.style.maskImage = maskImage;\n\t\t\t\t\twordEl.style.maskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.maskOrigin = \"left\";\n\t\t\t\t\twordEl.style.maskSize = totalAspectStr;\n\t\t\t\t} else {\n\t\t\t\t\twordEl.style.webkitMaskImage = maskImage;\n\t\t\t\t\twordEl.style.webkitMaskRepeat = \"no-repeat\";\n\t\t\t\t\twordEl.style.webkitMaskOrigin = \"left\";\n\t\t\t\t\twordEl.style.webkitMaskSize = totalAspectStr;\n\t\t\t\t}\n\t\t\t\t// 为了尽可能将渐变动画在相连的每个单词间近似衔接起来\n\t\t\t\t// 要综合每个单词的效果时间和间隙生成动画帧数组\n\t\t\t\tconst widthBeforeSelf =\n\t\t\t\t\tthis.splittedWords.slice(0, i).reduce((a, b) => a + b.width, 0) +\n\t\t\t\t\t(this.splittedWords[0] ? fadeWidth : 0);\n\t\t\t\tconst minOffset = -(word.width + word.padding * 2 + fadeWidth);\n\t\t\t\tconst clampOffset = (x: number) => Math.max(minOffset, Math.min(0, x));\n\t\t\t\tlet curPos = -widthBeforeSelf - word.width - word.padding - fadeWidth;\n\t\t\t\tlet timeOffset = 0;\n\t\t\t\tconst frames: Keyframe[] = [];\n\t\t\t\tlet lastPos = curPos;\n\t\t\t\tlet lastTime = 0;\n\t\t\t\tconst pushFrame = () => {\n\t\t\t\t\t// 此处如果添加过渡函数,会导致单词时序不准确,所以不添加\n\t\t\t\t\t// const easing = \"cubic-bezier(.33,.12,.83,.9)\";\n\t\t\t\t\tconst moveOffset = curPos - lastPos;\n\t\t\t\t\tconst time = Math.max(0, Math.min(1, timeOffset));\n\t\t\t\t\tconst duration = time - lastTime;\n\t\t\t\t\tconst d = Math.abs(duration / moveOffset);\n\t\t\t\t\t// 因为有可能会和之前的动画有边界\n\t\t\t\t\tif (curPos > minOffset && lastPos < minOffset) {\n\t\t\t\t\t\tconst staticTime = Math.abs(lastPos - minOffset) * d;\n\t\t\t\t\t\tconst value = `${clampOffset(lastPos)}px 0`;\n\t\t\t\t\t\tconst frame: Keyframe = {\n\t\t\t\t\t\t\toffset: lastTime + staticTime,\n\t\t\t\t\t\t\tmaskPosition: value,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tframes.push(frame);\n\t\t\t\t\t}\n\t\t\t\t\tif (curPos > 0 && lastPos < 0) {\n\t\t\t\t\t\tconst staticTime = Math.abs(lastPos) * d;\n\t\t\t\t\t\tconst value = `${clampOffset(curPos)}px 0`;\n\t\t\t\t\t\tconst frame: Keyframe = {\n\t\t\t\t\t\t\toffset: lastTime + staticTime,\n\t\t\t\t\t\t\tmaskPosition: value,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tframes.push(frame);\n\t\t\t\t\t}\n\t\t\t\t\tconst value = `${clampOffset(curPos)}px 0`;\n\t\t\t\t\tconst frame: Keyframe = {\n\t\t\t\t\t\toffset: time,\n\t\t\t\t\t\tmaskPosition: value,\n\t\t\t\t\t};\n\t\t\t\t\tframes.push(frame);\n\t\t\t\t\tlastPos = curPos;\n\t\t\t\t\tlastTime = time;\n\t\t\t\t};\n\t\t\t\tpushFrame();\n\t\t\t\tlet lastTimeStamp = 0;\n\t\t\t\tthis.splittedWords.forEach((otherWord, j) => {\n\t\t\t\t\t// 停顿\n\t\t\t\t\t{\n\t\t\t\t\t\tconst curTimeStamp = otherWord.startTime - this.lyricLine.startTime;\n\t\t\t\t\t\tconst staticDuration = curTimeStamp - lastTimeStamp;\n\t\t\t\t\t\ttimeOffset += staticDuration / totalFadeDuration;\n\t\t\t\t\t\tif (staticDuration > 0) pushFrame();\n\t\t\t\t\t\tlastTimeStamp = curTimeStamp;\n\t\t\t\t\t}\n\t\t\t\t\t// 移动\n\t\t\t\t\t{\n\t\t\t\t\t\tconst fadeDuration = otherWord.endTime - otherWord.startTime;\n\t\t\t\t\t\tconst rubySegments = this.getRubySegments(otherWord);\n\t\t\t\t\t\tconst rubyCharCount = rubySegments.reduce(\n\t\t\t\t\t\t\t(total, ruby) => total + ruby.word.length,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (rubyCharCount > 0) {\n\t\t\t\t\t\t\tconst widthPerChar = otherWord.width / rubyCharCount;\n\t\t\t\t\t\t\tlet charIndex = 0;\n\t\t\t\t\t\t\tfor (const ruby of rubySegments) {\n\t\t\t\t\t\t\t\tconst rubyStartTime = Number.isFinite(ruby.startTime)\n\t\t\t\t\t\t\t\t\t? ruby.startTime\n\t\t\t\t\t\t\t\t\t: otherWord.startTime;\n\t\t\t\t\t\t\t\tconst rubyEndTime = Number.isFinite(ruby.endTime)\n\t\t\t\t\t\t\t\t\t? ruby.endTime\n\t\t\t\t\t\t\t\t\t: otherWord.endTime;\n\t\t\t\t\t\t\t\tconst rubyStart = Math.max(rubyStartTime, otherWord.startTime);\n\t\t\t\t\t\t\t\tconst rubyEnd = Math.min(\n\t\t\t\t\t\t\t\t\tMath.max(rubyEndTime, rubyStart),\n\t\t\t\t\t\t\t\t\totherWord.endTime,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst rubyStartStamp = rubyStart - this.lyricLine.startTime;\n\t\t\t\t\t\t\t\tconst rubyStaticDuration = rubyStartStamp - lastTimeStamp;\n\t\t\t\t\t\t\t\ttimeOffset += rubyStaticDuration / totalFadeDuration;\n\t\t\t\t\t\t\t\tif (rubyStaticDuration > 0) pushFrame();\n\t\t\t\t\t\t\t\tlastTimeStamp = rubyStartStamp;\n\t\t\t\t\t\t\t\tconst rubyDuration = Math.max(0, rubyEnd - rubyStart);\n\t\t\t\t\t\t\t\tconst perCharDuration = rubyDuration / ruby.word.length;\n\t\t\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\t\t\tlet rubyCharIndex = 0;\n\t\t\t\t\t\t\t\t\trubyCharIndex < ruby.word.length;\n\t\t\t\t\t\t\t\t\trubyCharIndex++\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\ttimeOffset += perCharDuration / totalFadeDuration;\n\t\t\t\t\t\t\t\t\tcurPos += widthPerChar;\n\t\t\t\t\t\t\t\t\tif (j === 0 && charIndex === 0) {\n\t\t\t\t\t\t\t\t\t\tcurPos += fadeWidth * 1.5;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tj === this.splittedWords.length - 1 &&\n\t\t\t\t\t\t\t\t\t\tcharIndex === rubyCharCount - 1\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tcurPos += fadeWidth * 0.5;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (perCharDuration > 0) pushFrame();\n\t\t\t\t\t\t\t\t\tlastTimeStamp += perCharDuration;\n\t\t\t\t\t\t\t\t\tcharIndex++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst wordEndStamp = Math.max(\n\t\t\t\t\t\t\t\totherWord.endTime - this.lyricLine.startTime,\n\t\t\t\t\t\t\t\tlastTimeStamp,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst wordTailDuration = wordEndStamp - lastTimeStamp;\n\t\t\t\t\t\t\ttimeOffset += wordTailDuration / totalFadeDuration;\n\t\t\t\t\t\t\tif (wordTailDuration > 0) pushFrame();\n\t\t\t\t\t\t\tlastTimeStamp = wordEndStamp;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttimeOffset += fadeDuration / totalFadeDuration;\n\t\t\t\t\t\t\tcurPos += otherWord.width;\n\t\t\t\t\t\t\tif (j === 0) {\n\t\t\t\t\t\t\t\tcurPos += fadeWidth * 1.5;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (j === this.splittedWords.length - 1) {\n\t\t\t\t\t\t\t\tcurPos += fadeWidth * 0.5;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (fadeDuration > 0) pushFrame();\n\t\t\t\t\t\t\tlastTimeStamp += fadeDuration;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tfor (const a of word.maskAnimations) {\n\t\t\t\t\ta.cancel();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\t// TODO: 如果此处动画帧计算出错,需要一个后备方案\n\t\t\t\t\t// 此处如果添加过渡函数,会导致单词时序不准确,所以不添加\n\t\t\t\t\tconst ani = wordEl.animate(frames, {\n\t\t\t\t\t\tduration: totalFadeDuration || 1,\n\t\t\t\t\t\tid: `fade-word-${word.word}-${i}`,\n\t\t\t\t\t\tfill: \"both\",\n\t\t\t\t\t});\n\t\t\t\t\tani.pause();\n\t\t\t\t\tword.maskAnimations = [ani];\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.warn(\"应用渐变动画发生错误\", frames, totalFadeDuration, err);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tgetElement(): HTMLElement {\n\t\treturn this.element;\n\t}\n\toverride setTransform(\n\t\ttop: number = this.top,\n\t\tscale: number = this.scale,\n\t\topacity = 1,\n\t\tblur = 0,\n\t\tforce = false,\n\t\tdelay = 0,\n\t): void {\n\t\tsuper.setTransform(top, scale, opacity, blur, force, delay);\n\t\tconst beforeInSight = this.isInSight;\n\t\tconst enableSpring = this.lyricPlayer.getEnableSpring();\n\t\tthis.top = top;\n\t\tthis.scale = scale;\n\t\tthis.delay = (delay * 1000) | 0;\n\t\tconst main = this.element.children[0] as HTMLDivElement;\n\t\t// main.style.opacity = `${opacity *\n\t\t// \t(!this.hasFaded ? 1 : this.lyricPlayer._getIsNonDynamic() ? 1 : 0.3)\n\t\t// \t}`;\n\t\tmain.style.opacity = `${opacity}`;\n\t\t// trans.style.opacity = `${subopacity}`;\n\t\t// roman.style.opacity = `${subopacity}`;\n\t\tif (force || !enableSpring) {\n\t\t\tif (force) this.element.classList.add(styles.tmpDisableTransition);\n\t\t\t// this.lineWebAnimationTransforms.posX.setTargetPosition(left);\n\t\t\t// this.lineWebAnimationTransforms.posY.setTargetPosition(top);\n\t\t\t// this.lineWebAnimationTransforms.scale.setTargetPosition(scale);\n\t\t\tthis.lineTransforms.posY.setPosition(top);\n\t\t\tthis.lineTransforms.scale.setPosition(scale);\n\t\t\tif (!enableSpring) {\n\t\t\t\tconst afterInSight = this.isInSight;\n\t\t\t\tif (beforeInSight || afterInSight) {\n\t\t\t\t\tthis.show();\n\t\t\t\t} else {\n\t\t\t\t\tthis.hide();\n\t\t\t\t}\n\t\t\t} else this.rebuildStyle();\n\t\t\tif (force)\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tthis.element.classList.remove(styles.tmpDisableTransition);\n\t\t\t\t});\n\t\t} else {\n\t\t\t// this.lineWebAnimationTransforms.posX.stop();\n\t\t\t// this.lineWebAnimationTransforms.posY.stop();\n\t\t\t// this.lineWebAnimationTransforms.scale.stop();\n\t\t\tthis.lineTransforms.posY.setTargetPosition(top, delay);\n\t\t\tthis.lineTransforms.scale.setTargetPosition(scale);\n\t\t}\n\t}\n\tupdate(delta = 0): void {\n\t\tif (!this.lyricPlayer.getEnableSpring()) return;\n\t\tthis.lineTransforms.posY.update(delta);\n\t\tthis.lineTransforms.scale.update(delta);\n\t\tif (this.isInSight) {\n\t\t\tthis.show();\n\t\t\tif (this.maskImageDirty) {\n\t\t\t\tthis.updateMaskImage();\n\t\t\t}\n\t\t} else {\n\t\t\tthis.hide();\n\t\t}\n\t\tif (this.lyricPlayer.getEnableSpring()) {\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--bright-mask-alpha\",\n\t\t\t\t`${\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t0.0,\n\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t1.0,\n\t\t\t\t\t\t\tthis.lineTransforms.scale.getCurrentPosition() / 100 - 0.97,\n\t\t\t\t\t\t) / 0.03,\n\t\t\t\t\t) *\n\t\t\t\t\t\t0.8 +\n\t\t\t\t\t0.2\n\t\t\t\t}`,\n\t\t\t);\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--dark-mask-alpha\",\n\t\t\t\t`${\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t0.0,\n\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t1.0,\n\t\t\t\t\t\t\tthis.lineTransforms.scale.getCurrentPosition() / 100 - 0.97,\n\t\t\t\t\t\t) / 0.03,\n\t\t\t\t\t) *\n\t\t\t\t\t\t0.2 +\n\t\t\t\t\t0.2\n\t\t\t\t}`,\n\t\t\t);\n\t\t} else {\n\t\t\tconst computedStyle = window.getComputedStyle(this.element);\n\t\t\tconst transform = computedStyle.transform;\n\n\t\t\t// Extract the scale value from the transform property\n\t\t\tconst scale = getScaleFromTransform(transform);\n\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--bright-mask-alpha\",\n\t\t\t\t`${Math.max(0.0, Math.min(1.0, (scale - 0.97) / 0.03)) * 0.8 + 0.2}`,\n\t\t\t);\n\t\t\tthis.element.style.setProperty(\n\t\t\t\t\"--dark-mask-alpha\",\n\t\t\t\t`${Math.max(0.0, Math.min(1.0, (scale - 0.97) / 0.03)) * 0.2 + 0.2}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t_getDebugTargetPos(): string {\n\t\treturn `[位移: ${this.top}; 缩放: ${this.scale}; 延时: ${this.delay}]`;\n\t}\n\n\tget isInSight(): boolean {\n\t\tconst t = this.lineTransforms.posY.getCurrentPosition();\n\t\tconst h = this.lineSize[1];\n\t\tconst b = t + h;\n\t\tconst pb = this.lyricPlayer.size[1];\n\t\treturn !(t > pb + h || b < -h);\n\t}\n\tprivate disposeElements() {\n\t\tfor (const realWord of this.splittedWords) {\n\t\t\tfor (const a of realWord.elementAnimations) {\n\t\t\t\ta.cancel();\n\t\t\t}\n\t\t\tfor (const a of realWord.maskAnimations) {\n\t\t\t\ta.cancel();\n\t\t\t}\n\t\t\tfor (const sub of realWord.subElements) {\n\t\t\t\tsub.remove();\n\t\t\t\tsub.parentNode?.removeChild(sub);\n\t\t\t}\n\t\t\trealWord.elementAnimations = [];\n\t\t\trealWord.maskAnimations = [];\n\t\t\trealWord.subElements = [];\n\t\t\trealWord.mainElement.remove();\n\t\t\trealWord.mainElement.parentNode?.removeChild(realWord.mainElement);\n\t\t}\n\t\tthis.splittedWords = [];\n\t}\n\toverride dispose(): void {\n\t\tthis.disposeElements();\n\t\tthis.element.remove();\n\t}\n}\n","/**\n * @fileoverview\n * 一个播放歌词的组件,但是进行了部分效果的阉割精简,以尝试改善在低性能设备上的性能问题\n * @author SteveXMH\n */\n\nimport type { LyricLine } from \"../../interfaces.ts\";\nimport \"../../styles/index.css\";\nimport { debounce } from \"../../utils/debounce.ts\";\nimport { LyricPlayerBase } from \"../base.ts\";\nimport { LyricLineMouseEvent } from \"../dom/index.ts\";\nimport styles from \"./index.module.css\";\nimport { LyricLineEl, type RawLyricLineMouseEvent } from \"./lyric-line.ts\";\n\n/**\n * 歌词播放组件,本框架的核心组件\n *\n * 尽可能贴切 Apple Music for iPad 的歌词效果设计,且做了力所能及的优化措施\n */\nexport class DomSlimLyricPlayer extends LyricPlayerBase {\n\toverride currentLyricLineObjects: LyricLineEl[] = [];\n\n\tprivate debounceCalcLayout = debounce(\n\t\t() =>\n\t\t\tthis.calcLayout(true).then(() =>\n\t\t\t\tthis.currentLyricLineObjects.map(async (el, i) => {\n\t\t\t\t\tel.markMaskImageDirty(\"DomLyricPlayer onResize\");\n\t\t\t\t\tawait el.waitMaskImageUpdated();\n\t\t\t\t\tif (this.hotLines.has(i)) {\n\t\t\t\t\t\tel.enable(this.currentTime);\n\t\t\t\t\t\tel.resume();\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t1000,\n\t);\n\n\toverride onResize(): void {\n\t\tconst computedStyles = getComputedStyle(this.element);\n\t\tthis._baseFontSize = Number.parseFloat(computedStyles.fontSize);\n\t\tconst innerWidth =\n\t\t\tthis.element.clientWidth -\n\t\t\tNumber.parseFloat(computedStyles.paddingLeft) -\n\t\t\tNumber.parseFloat(computedStyles.paddingRight);\n\t\tconst innerHeight =\n\t\t\tthis.element.clientHeight -\n\t\t\tNumber.parseFloat(computedStyles.paddingTop) -\n\t\t\tNumber.parseFloat(computedStyles.paddingBottom);\n\t\tthis.innerSize[0] = innerWidth;\n\t\tthis.innerSize[1] = innerHeight;\n\t\tthis.rebuildStyle();\n\t\t// for (const obj of this.currentLyricLineObjects) {\n\t\t// \tif (!obj.getElement().classList.contains(styles.dirty))\n\t\t// \t\tobj.getElement().classList.add(styles.dirty);\n\t\t// }\n\t\tthis.debounceCalcLayout();\n\t}\n\n\treadonly supportPlusLighter: boolean = CSS.supports(\n\t\t\"mix-blend-mode\",\n\t\t\"plus-lighter\",\n\t);\n\treadonly supportMaskImage: boolean = CSS.supports(\"mask-image\", \"none\");\n\treadonly innerSize: [number, number] = [0, 0];\n\tprivate readonly onLineClickedHandler = (e: RawLyricLineMouseEvent) => {\n\t\tconst evt = new LyricLineMouseEvent(\n\t\t\tthis.lyricLinesIndexes.get(e.line) ?? -1,\n\t\t\te.line,\n\t\t\te,\n\t\t);\n\t\tif (!this.dispatchEvent(evt)) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\t};\n\t/**\n\t * 是否为非逐词歌词\n\t * @internal\n\t */\n\t_getIsNonDynamic(): boolean {\n\t\treturn this.isNonDynamic;\n\t}\n\tprivate _baseFontSize = Number.parseFloat(\n\t\tgetComputedStyle(this.element).fontSize,\n\t);\n\tpublic get baseFontSize(): number {\n\t\treturn this._baseFontSize;\n\t}\n\tconstructor() {\n\t\tsuper();\n\t\tthis.onResize();\n\t\tthis.element.classList.add(\"amll-lyric-player\", \"dom-slim\");\n\t\tif (this.disableSpring) {\n\t\t\tthis.element.classList.add(styles.disableSpring);\n\t\t}\n\t}\n\n\tprivate rebuildStyle() {\n\t\tconst width = this.innerSize[0];\n\t\tconst height = this.innerSize[1];\n\t\tthis.element.style.setProperty(\"--amll-lp-width\", `${width.toFixed(4)}px`);\n\t\tthis.element.style.setProperty(\n\t\t\t\"--amll-lp-height\",\n\t\t\t`${height.toFixed(4)}px`,\n\t\t);\n\t}\n\n\toverride setWordFadeWidth(value = 0.5): void {\n\t\tsuper.setWordFadeWidth(value);\n\t\tfor (const el of this.currentLyricLineObjects) {\n\t\t\tel.markMaskImageDirty(\"DomLyricPlayer setWordFadeWidth\");\n\t\t}\n\t}\n\n\t/**\n\t * 设置当前播放歌词,要注意传入后这个数组内的信息不得修改,否则会发生错误\n\t * @param lines 歌词数组\n\t * @param initialTime 初始时间,默认为 0\n\t */\n\toverride setLyricLines(lines: LyricLine[], initialTime = 0): void {\n\t\tsuper.setLyricLines(lines, initialTime);\n\t\tif (this.hasDuetLine) {\n\t\t\tthis.element.classList.add(styles.hasDuetLine);\n\t\t} else {\n\t\t\tthis.element.classList.remove(styles.hasDuetLine);\n\t\t}\n\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.removeMouseEventListener(\"click\", this.onLineClickedHandler);\n\t\t\tline.removeMouseEventListener(\"contextmenu\", this.onLineClickedHandler);\n\t\t\tline.dispose();\n\t\t}\n\n\t\t// 创建新的歌词行元素\n\t\tthis.currentLyricLineObjects = this.processedLines.map((line, i) => {\n\t\t\tconst lineEl = new LyricLineEl(this, line);\n\t\t\tlineEl.addMouseEventListener(\"click\", this.onLineClickedHandler);\n\t\t\tlineEl.addMouseEventListener(\"contextmenu\", this.onLineClickedHandler);\n\t\t\tthis.element.appendChild(lineEl.getElement());\n\t\t\tthis.lyricLinesIndexes.set(lineEl, i);\n\t\t\tlineEl.markMaskImageDirty(\"DomLyricPlayer setLyricLines\");\n\t\t\treturn lineEl;\n\t\t});\n\n\t\tthis.setLinePosXSpringParams({});\n\t\tthis.setLinePosYSpringParams({});\n\t\tthis.setLineScaleSpringParams({});\n\t\tthis.calcLayout(true).then(() => {\n\t\t\tthis.initialLayoutFinished = true;\n\t\t});\n\t}\n\n\toverride pause(): void {\n\t\tsuper.pause();\n\t\tthis.interludeDots.pause();\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.pause();\n\t\t}\n\t}\n\n\toverride resume(): void {\n\t\tsuper.resume();\n\t\tthis.interludeDots.resume();\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.resume();\n\t\t}\n\t}\n\n\toverride update(delta = 0): void {\n\t\tif (!this.initialLayoutFinished) return;\n\t\tsuper.update(delta);\n\t\tif (!this.isPageVisible) return;\n\t\tconst deltaS = delta / 1000;\n\t\tfor (const line of this.currentLyricLineObjects) {\n\t\t\tline.update(deltaS);\n\t\t}\n\t}\n\n\toverride async calcLayout(sync?: boolean): Promise<void> {\n\t\tawait super.calcLayout(sync);\n\t\tconst curLine = this.currentLyricLineObjects[this.targetAlignIndex];\n\t\tconst curLineEl = curLine.getElement();\n\t\tconst curLineVisibility = curLineEl.checkVisibility({\n\t\t\tcontentVisibilityAuto: true,\n\t\t});\n\t\tconst playerTop = this.element.getBoundingClientRect().top;\n\t\tif (!curLineVisibility) {\n\t\t\tcurLineEl.scrollIntoView({\n\t\t\t\tblock: \"center\",\n\t\t\t\tbehavior: \"instant\",\n\t\t\t});\n\t\t}\n\t\tconst curLineHeight = curLineEl.clientHeight;\n\t\tconst curLineRect = curLineEl.getBoundingClientRect();\n\t\tlet scrollToPos =\n\t\t\tcurLineRect.top - playerTop - this.size[1] * this.alignPosition;\n\t\tif (curLine) {\n\t\t\tswitch (this.alignAnchor) {\n\t\t\t\tcase \"bottom\":\n\t\t\t\t\tscrollToPos += curLineHeight;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"center\":\n\t\t\t\t\tscrollToPos += curLineHeight / 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"top\":\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tthis.element.scrollBy({\n\t\t\ttop: scrollToPos,\n\t\t\tbehavior: \"smooth\",\n\t\t});\n\t}\n\n\toverride dispose(): void {\n\t\tsuper.dispose();\n\t\tthis.element.remove();\n\t\tfor (const el of this.currentLyricLineObjects) {\n\t\t\tel.dispose();\n\t\t}\n\t\tthis.bottomLine.dispose();\n\t\tthis.interludeDots.dispose();\n\t}\n}\n","import { DomLyricPlayer } from \"./dom/index.ts\";\n\nexport { LyricPlayerBase } from \"./base.ts\";\nexport * from \"./dom/index.ts\";\nexport * from \"./dom-slim/index.ts\";\n\n/**\n * 歌词中不雅用语的掩码模式\n */\nenum MaskObsceneWordsMode {\n\t/** 禁用任何不雅用语掩码 */\n\tDisabled = \"\",\n\t/** 完全掩码所有不雅用语 */\n\tFullMask = \"full-mask\",\n\t/** 保留首尾字符,屏蔽中间字符 */\n\tPartialMask = \"partial-mask\",\n}\n\n/**\n * 歌词行的渲染模式\n * @internal\n */\nenum LyricLineRenderMode {\n\tSOLID = 0,\n\tGRADIENT = 1,\n}\n\nexport {\n\t/**\n\t * 默认导出的歌词播放组件\n\t */\n\tDomLyricPlayer as LyricPlayer,\n\tLyricLineRenderMode,\n\tMaskObsceneWordsMode,\n};\n"],"mappings":"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"}
|