diff --git a/packages/artplayer-plugin-danmuku/ARCHITECTURE.md b/packages/artplayer-plugin-danmuku/ARCHITECTURE.md
index 616e16a44..74e9a09b4 100644
--- a/packages/artplayer-plugin-danmuku/ARCHITECTURE.md
+++ b/packages/artplayer-plugin-danmuku/ARCHITECTURE.md
@@ -136,6 +136,14 @@ legacy build targets remain es2020 and es2015; syntax lowering does not polyfill
## Scheduling ownership
+The root `art.template.$danmuku` belongs to the core template, not this plugin.
+The Mask plugin captures this layer and the core video, and listens to core
+ready/destroy; it does not read Danmuku queues, owners or plugin events. Renderer
+cleanup owns individual comment nodes. Reset/replacement must preserve the root
+identity and external mask styles; hide/show owns only its visibility opacity.
+CSS-mask boundary tests do not establish model inference, SDK cleanup or complete
+Mask integration. Those remain responsibilities of the Mask migration tasks.
+
Keep at most one pending RAF and one asynchronous preparation batch. Native `play`
and `playing` both invoke the existing start path and retain its events, but
must not create competing loops. Ready items precede wait items; wait selection
diff --git a/refactor/baselines/danmuku-mask-contract.md b/refactor/baselines/danmuku-mask-contract.md
index 8634e8104..85436aeda 100644
--- a/refactor/baselines/danmuku-mask-contract.md
+++ b/refactor/baselines/danmuku-mask-contract.md
@@ -53,7 +53,10 @@
`setBackend` fulfilled false 视为已执行 fallback。
registrar 捕获 `art.template.$video/$danmuku`,订阅 ready→start、destroy→stop。
-必须在 Danmuku 插件建立 `$danmuku` 后注册;demo 正是先 Danmuku 再 Mask。
+需要核心模板已经提供 `$danmuku/$video`;demo 使用先 Danmuku 再 Mask 的顺序。
+2026-09-13(PKG-DANMUKU-07)纠正初始记录:`$danmuku` 由核心模板创建,
+不是 Danmuku 插件创建,因此 demo 顺序本身不构成 Mask 对 Danmuku 注册的硬依赖。
+Mask 源码不读取 Danmuku 队列、owner 或插件事件;完整模型组合仍待 Mask 验收。
start 建立 2D canvas 并设置 `$danmuku.style`:maskMode=alpha、maskSize=contain、
maskRepeat=no-repeat、backgroundSize=contain、backgroundRepeat=no-repeat。
每轮以视频固有尺寸推理,白色前景/黑色背景生成 binary mask,drawMask 后将 RGB
diff --git a/refactor/baselines/danmuku-stability-validation.json b/refactor/baselines/danmuku-stability-validation.json
new file mode 100644
index 000000000..e25723164
--- /dev/null
+++ b/refactor/baselines/danmuku-stability-validation.json
@@ -0,0 +1,6157 @@
+{
+ "schemaVersion": 1,
+ "task": "PKG-DANMUKU-07",
+ "status": "done",
+ "capturedAt": "2026-09-13T15:15:04.455Z",
+ "baselineCommit": "4f559cb31d6b69a37439c6db2d32ca28ae5c78f3",
+ "report": {
+ "file": "refactor/.cache/danmuku07-stability-final.json",
+ "sha256": "474aa2aa3b0fa8f5700307db9a05d2253e15ab3d90f7cd2a1434c1b5ff131bc8"
+ },
+ "stats": {
+ "startTime": "2026-09-13T15:08:26.510Z",
+ "duration": 308645.533,
+ "expected": 66,
+ "skipped": 0,
+ "unexpected": 0,
+ "flaky": 0
+ },
+ "groups": {
+ "chromium/danmuku-mask-boundary.spec.js": 2,
+ "firefox/danmuku-mask-boundary.spec.js": 2,
+ "webkit/danmuku-mask-boundary.spec.js": 2,
+ "chromium/danmuku-resources.spec.js": 16,
+ "firefox/danmuku-resources.spec.js": 16,
+ "webkit/danmuku-resources.spec.js": 16,
+ "chromium/danmuku-stability.spec.js": 4,
+ "firefox/danmuku-stability.spec.js": 4,
+ "webkit/danmuku-stability.spec.js": 4
+ },
+ "versions": {
+ "chromium": {
+ "browser": "153.0.8010.12",
+ "platform": "win32"
+ },
+ "firefox": {
+ "browser": "155.0",
+ "platform": "win32"
+ },
+ "webkit": {
+ "browser": "26.6",
+ "platform": "win32"
+ }
+ },
+ "loads": [
+ {
+ "engine": "chromium",
+ "implementation": "published",
+ "rowsPerSecond": 2,
+ "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.374546,
+ "startWall": 627.8000000119209,
+ "endWall": 14764,
+ "time": 14.477616,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 24,
+ "states": {
+ "wait": 24,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 4,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 24,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 846,
+ "p50": 16.699999999999818,
+ "p95": 16.799999999999272,
+ "max": 16.80000000000109
+ },
+ "framesMediaSeconds": {
+ "count": 846,
+ "p50": 0.0166590000000002,
+ "p95": 0.018034000000000106,
+ "max": 0.01936200000000099
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.477616,
+ "startWall": 14773.699999988079,
+ "endWall": 28914.5,
+ "time": 28.577985,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 48,
+ "states": {
+ "wait": 48,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 5,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 48,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 846,
+ "p50": 16.69999999999891,
+ "p95": 16.700000000000728,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 846,
+ "p50": 0.016647999999999996,
+ "p95": 0.018342000000000525,
+ "max": 0.023869999999998726
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.577985,
+ "startWall": 28922,
+ "endWall": 43066.10000002384,
+ "time": 42.680636,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 72,
+ "states": {
+ "wait": 72,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 6,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 72,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 846,
+ "p50": 16.69999999999709,
+ "p95": 16.799999999995634,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 846,
+ "p50": 0.0166959999999996,
+ "p95": 0.01811000000000007,
+ "max": 0.020167000000000712
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2538,
+ "p50": 16.69999999999709,
+ "p95": 16.700000000004366,
+ "max": 66.70000000000073
+ },
+ "framesMediaSeconds": {
+ "count": 2538,
+ "p50": 0.016670000000004848,
+ "p95": 0.018145000000000522,
+ "max": 0.05940100000000115
+ },
+ "samplingWallMs": {
+ "count": 2607,
+ "p50": 16.69999998807907,
+ "p95": 17.80000001192093,
+ "max": 83.90000003576279
+ },
+ "samplingMediaSeconds": {
+ "count": 2607,
+ "p50": 0.016633999999999816,
+ "p95": 0.018132999999999733,
+ "max": 0.0597139999999996
+ }
+ },
+ "totalVisible": 72,
+ "uniqueVisible": 72,
+ "recycled": 72,
+ "callbacks": 75,
+ "allocations": 6,
+ "reuses": 69,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 75,
+ "replies": 75,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "chromium",
+ "implementation": "published",
+ "rowsPerSecond": 20,
+ "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.369621,
+ "startWall": 586.3999999761581,
+ "endWall": 14722.399999976158,
+ "time": 14.460377,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 240,
+ "states": {
+ "wait": 240,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 22,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 240,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 845,
+ "p50": 16.699999999999818,
+ "p95": 16.700000000000728,
+ "max": 16.80000000000109
+ },
+ "framesMediaSeconds": {
+ "count": 845,
+ "p50": 0.016639999999998878,
+ "p95": 0.018498000000001014,
+ "max": 0.019878999999999536
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.460377,
+ "startWall": 14737.300000011921,
+ "endWall": 28888.399999976158,
+ "time": 28.579458,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 480,
+ "states": {
+ "wait": 480,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 23,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 480,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 846,
+ "p50": 16.69999999999891,
+ "p95": 16.799999999999272,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 846,
+ "p50": 0.01665800000000317,
+ "p95": 0.018109000000002595,
+ "max": 0.02022799999999947
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.579458,
+ "startWall": 28905.399999976158,
+ "endWall": 43037.10000002384,
+ "time": 42.662662,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 720,
+ "states": {
+ "wait": 720,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 24,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 720,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 845,
+ "p50": 16.69999999999709,
+ "p95": 16.700000000004366,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 845,
+ "p50": 0.016683000000000447,
+ "p95": 0.018039000000001693,
+ "max": 0.01981900000000536
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2536,
+ "p50": 16.69999999999709,
+ "p95": 16.700000000004366,
+ "max": 83.40000000000146
+ },
+ "framesMediaSeconds": {
+ "count": 2536,
+ "p50": 0.016664000000002233,
+ "p95": 0.018217999999997403,
+ "max": 0.07596999999999987
+ },
+ "samplingWallMs": {
+ "count": 2603,
+ "p50": 16.600000023841858,
+ "p95": 17.80000001192093,
+ "max": 99.30000001192093
+ },
+ "samplingMediaSeconds": {
+ "count": 2603,
+ "p50": 0.016636000000005424,
+ "p95": 0.018202999999999747,
+ "max": 0.07654499999999942
+ }
+ },
+ "totalVisible": 720,
+ "uniqueVisible": 720,
+ "recycled": 720,
+ "callbacks": 723,
+ "allocations": 24,
+ "reuses": 699,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 723,
+ "replies": 723,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "chromium",
+ "implementation": "candidate",
+ "rowsPerSecond": 2,
+ "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.369808,
+ "startWall": 609.9000000357628,
+ "endWall": 14777.800000011921,
+ "time": 14.494251,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 24,
+ "states": {
+ "wait": 24,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 24,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 847,
+ "p50": 16.699999999999818,
+ "p95": 16.700000000000728,
+ "max": 16.80000000000109
+ },
+ "framesMediaSeconds": {
+ "count": 847,
+ "p50": 0.016671999999999798,
+ "p95": 0.017968999999999014,
+ "max": 0.019351999999999592
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.494251,
+ "startWall": 14789.400000035763,
+ "endWall": 28912.200000047684,
+ "time": 28.58184,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 48,
+ "states": {
+ "wait": 48,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 48,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 845,
+ "p50": 16.69999999999891,
+ "p95": 16.799999999999272,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 845,
+ "p50": 0.016664999999999708,
+ "p95": 0.01806399999999897,
+ "max": 0.024385999999999797
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.58184,
+ "startWall": 28921.80000001192,
+ "endWall": 43076.200000047684,
+ "time": 42.715746,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 72,
+ "states": {
+ "wait": 72,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 72,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 847,
+ "p50": 16.69999999999709,
+ "p95": 16.700000000004366,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 847,
+ "p50": 0.016697000000000628,
+ "p95": 0.01815099999999603,
+ "max": 0.019627999999997314
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2539,
+ "p50": 16.69999999999709,
+ "p95": 16.700000000004366,
+ "max": 66.70000000000073
+ },
+ "framesMediaSeconds": {
+ "count": 2539,
+ "p50": 0.016674000000001854,
+ "p95": 0.018076000000000647,
+ "max": 0.061954999999999316
+ },
+ "samplingWallMs": {
+ "count": 2536,
+ "p50": 16.69999998807907,
+ "p95": 17.899999976158142,
+ "max": 83.09999996423721
+ },
+ "samplingMediaSeconds": {
+ "count": 2536,
+ "p50": 0.016676000000000357,
+ "p95": 0.018077999999995598,
+ "max": 0.0623389999999997
+ }
+ },
+ "totalVisible": 72,
+ "uniqueVisible": 72,
+ "recycled": 72,
+ "callbacks": 72,
+ "allocations": 3,
+ "reuses": 69,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 72,
+ "replies": 72,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "chromium",
+ "implementation": "candidate",
+ "rowsPerSecond": 20,
+ "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.374623,
+ "startWall": 604.1999999880791,
+ "endWall": 14771.5,
+ "time": 14.496561,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 240,
+ "states": {
+ "wait": 240,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 21,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 240,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 847,
+ "p50": 16.699999999999818,
+ "p95": 16.700000000000728,
+ "max": 16.80000000000109
+ },
+ "framesMediaSeconds": {
+ "count": 847,
+ "p50": 0.01671499999999959,
+ "p95": 0.018153999999999115,
+ "max": 0.019287000000000276
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.496561,
+ "startWall": 14789,
+ "endWall": 28950,
+ "time": 28.613425,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 480,
+ "states": {
+ "wait": 480,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 21,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 480,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 847,
+ "p50": 16.69999999999891,
+ "p95": 16.700000000000728,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 847,
+ "p50": 0.01666099999999915,
+ "p95": 0.018369999999997333,
+ "max": 0.020493999999999346
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.613425,
+ "startWall": 28967.600000023842,
+ "endWall": 43120.69999998808,
+ "time": 42.719133,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 720,
+ "states": {
+ "wait": 720,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 21,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 720,
+ "validStateMembers": true,
+ "heap": {
+ "used": 10000000,
+ "total": 10000000
+ },
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 846,
+ "p50": 16.69999999999709,
+ "p95": 16.799999999995634,
+ "max": 16.80000000000291
+ },
+ "framesMediaSeconds": {
+ "count": 846,
+ "p50": 0.016661999999996624,
+ "p95": 0.018042000000001224,
+ "max": 0.019764000000002113
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2540,
+ "p50": 16.69999999999709,
+ "p95": 16.700000000004366,
+ "max": 83.40000000000146
+ },
+ "framesMediaSeconds": {
+ "count": 2540,
+ "p50": 0.01668199999999942,
+ "p95": 0.0182399999999987,
+ "max": 0.06178000000000239
+ },
+ "samplingWallMs": {
+ "count": 2537,
+ "p50": 16.69999998807907,
+ "p95": 17.80000001192093,
+ "max": 100.40000003576279
+ },
+ "samplingMediaSeconds": {
+ "count": 2537,
+ "p50": 0.016683999999997923,
+ "p95": 0.0182399999999987,
+ "max": 0.06213999999999942
+ }
+ },
+ "totalVisible": 720,
+ "uniqueVisible": 720,
+ "recycled": 720,
+ "callbacks": 720,
+ "allocations": 21,
+ "reuses": 699,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 720,
+ "replies": 720,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "firefox",
+ "implementation": "published",
+ "rowsPerSecond": 2,
+ "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.425651,
+ "startWall": 728,
+ "endWall": 14945,
+ "time": 14.549274,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 24,
+ "states": {
+ "wait": 24,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 4,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 24,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 848,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 21.579999999999927
+ },
+ "framesMediaSeconds": {
+ "count": 848,
+ "p50": 0,
+ "p95": 0.04182500000000111,
+ "max": 0.04531200000000002
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.549274,
+ "startWall": 14965,
+ "endWall": 29244,
+ "time": 28.779661,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 48,
+ "states": {
+ "wait": 48,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 5,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 48,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 852,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 20.720000000001164
+ },
+ "framesMediaSeconds": {
+ "count": 852,
+ "p50": 0,
+ "p95": 0.0414500000000011,
+ "max": 0.044920999999998656
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.779661,
+ "startWall": 29256,
+ "endWall": 43519,
+ "time": 42.950316,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 72,
+ "states": {
+ "wait": 72,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 6,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 72,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 851,
+ "p50": 16.660000000003492,
+ "p95": 16.68000000000029,
+ "max": 19.81999999999971
+ },
+ "framesMediaSeconds": {
+ "count": 851,
+ "p50": 0,
+ "p95": 0.0416450000000026,
+ "max": 0.04536300000000182
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2551,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 100
+ },
+ "framesMediaSeconds": {
+ "count": 2551,
+ "p50": 0,
+ "p95": 0.041733000000000686,
+ "max": 0.04536300000000182
+ },
+ "samplingWallMs": {
+ "count": 2624,
+ "p50": 17,
+ "p95": 18,
+ "max": 101
+ },
+ "samplingMediaSeconds": {
+ "count": 2624,
+ "p50": 0,
+ "p95": 0.041701999999999906,
+ "max": 0.04536300000000182
+ }
+ },
+ "totalVisible": 72,
+ "uniqueVisible": 72,
+ "recycled": 72,
+ "callbacks": 75,
+ "allocations": 6,
+ "reuses": 69,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 75,
+ "replies": 75,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "firefox",
+ "implementation": "published",
+ "rowsPerSecond": 20,
+ "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.424629,
+ "startWall": 718,
+ "endWall": 15066,
+ "time": 14.695414,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 240,
+ "states": {
+ "wait": 240,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 23,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 240,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 856,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 20.699999999999818
+ },
+ "framesMediaSeconds": {
+ "count": 856,
+ "p50": 0,
+ "p95": 0.041786999999999797,
+ "max": 0.04524600000000012
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.695414,
+ "startWall": 15087,
+ "endWall": 29354,
+ "time": 28.8765,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 480,
+ "states": {
+ "wait": 480,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 24,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 480,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 850,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 20.979999999999563
+ },
+ "framesMediaSeconds": {
+ "count": 850,
+ "p50": 0,
+ "p95": 0.04186299999999932,
+ "max": 0.045232999999999635
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.8765,
+ "startWall": 29376,
+ "endWall": 43637,
+ "time": 43.066147,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 720,
+ "states": {
+ "wait": 720,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 24,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 720,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 851,
+ "p50": 16.660000000003492,
+ "p95": 16.68000000000029,
+ "max": 18.860000000000582
+ },
+ "framesMediaSeconds": {
+ "count": 851,
+ "p50": 0,
+ "p95": 0.041758000000001516,
+ "max": 0.04478300000000246
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2557,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 116.67999999999665
+ },
+ "framesMediaSeconds": {
+ "count": 2557,
+ "p50": 0,
+ "p95": 0.04180399999999995,
+ "max": 0.04524600000000012
+ },
+ "samplingWallMs": {
+ "count": 2631,
+ "p50": 17,
+ "p95": 18,
+ "max": 116
+ },
+ "samplingMediaSeconds": {
+ "count": 2631,
+ "p50": 0,
+ "p95": 0.04177699999999618,
+ "max": 0.04524600000000012
+ }
+ },
+ "totalVisible": 720,
+ "uniqueVisible": 720,
+ "recycled": 720,
+ "callbacks": 723,
+ "allocations": 24,
+ "reuses": 699,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 723,
+ "replies": 723,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "firefox",
+ "implementation": "candidate",
+ "rowsPerSecond": 2,
+ "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.427679,
+ "startWall": 714,
+ "endWall": 14964,
+ "time": 14.596651,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 24,
+ "states": {
+ "wait": 24,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 24,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 850,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 21.699999999999818
+ },
+ "framesMediaSeconds": {
+ "count": 850,
+ "p50": 0,
+ "p95": 0.04170599999999958,
+ "max": 0.04553100000000043
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.596651,
+ "startWall": 14976,
+ "endWall": 29230,
+ "time": 28.767115,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 48,
+ "states": {
+ "wait": 48,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 48,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 850,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 21.260000000002037
+ },
+ "framesMediaSeconds": {
+ "count": 850,
+ "p50": 0,
+ "p95": 0.04095400000000282,
+ "max": 0.04606899999999925
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.767115,
+ "startWall": 29240,
+ "endWall": 43452,
+ "time": 42.937943,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 72,
+ "states": {
+ "wait": 72,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 72,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 848,
+ "p50": 16.660000000003492,
+ "p95": 16.68000000000029,
+ "max": 18.720000000001164
+ },
+ "framesMediaSeconds": {
+ "count": 848,
+ "p50": 0,
+ "p95": 0.04165899999999567,
+ "max": 0.04530800000000568
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2548,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 100
+ },
+ "framesMediaSeconds": {
+ "count": 2548,
+ "p50": 0,
+ "p95": 0.041519000000000084,
+ "max": 0.04606899999999925
+ },
+ "samplingWallMs": {
+ "count": 2548,
+ "p50": 17,
+ "p95": 18,
+ "max": 99
+ },
+ "samplingMediaSeconds": {
+ "count": 2548,
+ "p50": 0,
+ "p95": 0.041519000000000084,
+ "max": 0.04606899999999925
+ }
+ },
+ "totalVisible": 72,
+ "uniqueVisible": 72,
+ "recycled": 72,
+ "callbacks": 72,
+ "allocations": 3,
+ "reuses": 69,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 72,
+ "replies": 72,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "firefox",
+ "implementation": "candidate",
+ "rowsPerSecond": 20,
+ "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.181611,
+ "startWall": 437,
+ "endWall": 14704,
+ "time": 14.375495,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 240,
+ "states": {
+ "wait": 240,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 21,
+ "pooled": 21,
+ "uniquePool": 21,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 240,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 851,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 21.0600000000004
+ },
+ "framesMediaSeconds": {
+ "count": 851,
+ "p50": 0,
+ "p95": 0.0420170000000013,
+ "max": 0.04489000000000054
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.375495,
+ "startWall": 14730,
+ "endWall": 28990,
+ "time": 28.559151,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 480,
+ "states": {
+ "wait": 480,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 22,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 480,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 850,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 20.92000000000189
+ },
+ "framesMediaSeconds": {
+ "count": 850,
+ "p50": 0,
+ "p95": 0.04180500000000009,
+ "max": 0.04524799999999907
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 28.559151,
+ "startWall": 29012,
+ "endWall": 43243,
+ "time": 42.690484,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 720,
+ "states": {
+ "wait": 720,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 22,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 720,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 849,
+ "p50": 16.660000000003492,
+ "p95": 16.68000000000029,
+ "max": 19
+ },
+ "framesMediaSeconds": {
+ "count": 849,
+ "p50": 0,
+ "p95": 0.04203499999999849,
+ "max": 0.04544299999999879
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 2550,
+ "p50": 16.659999999999854,
+ "p95": 16.68000000000029,
+ "max": 116.66000000000167
+ },
+ "framesMediaSeconds": {
+ "count": 2550,
+ "p50": 0,
+ "p95": 0.04198500000000038,
+ "max": 0.04544299999999879
+ },
+ "samplingWallMs": {
+ "count": 2550,
+ "p50": 17,
+ "p95": 18,
+ "max": 117
+ },
+ "samplingMediaSeconds": {
+ "count": 2550,
+ "p50": 0,
+ "p95": 0.04198500000000038,
+ "max": 0.04544299999999879
+ }
+ },
+ "totalVisible": 720,
+ "uniqueVisible": 720,
+ "recycled": 720,
+ "callbacks": 720,
+ "allocations": 22,
+ "reuses": 698,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 720,
+ "replies": 720,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "webkit",
+ "implementation": "published",
+ "rowsPerSecond": 2,
+ "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.2676458,
+ "startWall": 1302,
+ "endWall": 16269,
+ "time": 15.0319999,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 24,
+ "states": {
+ "wait": 24,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 4,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 24,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 358,
+ "p50": 45,
+ "p95": 61,
+ "max": 64
+ },
+ "framesMediaSeconds": {
+ "count": 358,
+ "p50": 0.045270799999999056,
+ "p95": 0.06116659999999996,
+ "max": 0.06383330000000065
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 15.0319999,
+ "startWall": 16311,
+ "endWall": 31301,
+ "time": 29.7106039,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 48,
+ "states": {
+ "wait": 48,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 5,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 48,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 363,
+ "p50": 45,
+ "p95": 61,
+ "max": 76
+ },
+ "framesMediaSeconds": {
+ "count": 363,
+ "p50": 0.045270900000002,
+ "p95": 0.06120830000000055,
+ "max": 0.07685419999999965
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 29.7106039,
+ "startWall": 31312,
+ "endWall": 46136,
+ "time": 44.2841962,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 72,
+ "states": {
+ "wait": 72,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 6,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 72,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 370,
+ "p50": 45,
+ "p95": 49,
+ "max": 78
+ },
+ "framesMediaSeconds": {
+ "count": 370,
+ "p50": 0.044770800000002,
+ "p95": 0.049208300000003646,
+ "max": 0.07760420000000323
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 1091,
+ "p50": 45,
+ "p95": 61,
+ "max": 365
+ },
+ "framesMediaSeconds": {
+ "count": 1091,
+ "p50": 0.045083300000001714,
+ "p95": 0.060958299999999355,
+ "max": 0.07760420000000323
+ },
+ "samplingWallMs": {
+ "count": 1120,
+ "p50": 45,
+ "p95": 61,
+ "max": 365
+ },
+ "samplingMediaSeconds": {
+ "count": 1120,
+ "p50": 0.04497920000000022,
+ "p95": 0.06087510000000007,
+ "max": 0.07762500000000472
+ }
+ },
+ "totalVisible": 72,
+ "uniqueVisible": 72,
+ "recycled": 72,
+ "callbacks": 75,
+ "allocations": 6,
+ "reuses": 69,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 75,
+ "replies": 75,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "webkit",
+ "implementation": "published",
+ "rowsPerSecond": 20,
+ "sha256": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.2983958,
+ "startWall": 1309,
+ "endWall": 16297,
+ "time": 15.0258749,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 240,
+ "states": {
+ "wait": 240,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 23,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 240,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 220,
+ "p50": 77,
+ "p95": 79,
+ "max": 93
+ },
+ "framesMediaSeconds": {
+ "count": 220,
+ "p50": 0.07679159999999996,
+ "p95": 0.07877080000000003,
+ "max": 0.09327089999999982
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 15.0258749,
+ "startWall": 16320,
+ "endWall": 31241,
+ "time": 29.6541872,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 480,
+ "states": {
+ "wait": 480,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 24,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 480,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 219,
+ "p50": 77,
+ "p95": 79,
+ "max": 93
+ },
+ "framesMediaSeconds": {
+ "count": 219,
+ "p50": 0.07679169999999758,
+ "p95": 0.07897920000000269,
+ "max": 0.09302089999999907
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 29.6541872,
+ "startWall": 31285,
+ "endWall": 46222,
+ "time": 44.2532795,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 720,
+ "states": {
+ "wait": 720,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 25,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 720,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 220,
+ "p50": 77,
+ "p95": 79,
+ "max": 94
+ },
+ "framesMediaSeconds": {
+ "count": 220,
+ "p50": 0.07668759999999963,
+ "p95": 0.07902080000000211,
+ "max": 0.09408340000000237
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 659,
+ "p50": 77,
+ "p95": 79,
+ "max": 414
+ },
+ "framesMediaSeconds": {
+ "count": 659,
+ "p50": 0.07675000000000054,
+ "p95": 0.07889580000000151,
+ "max": 0.09408340000000237
+ },
+ "samplingWallMs": {
+ "count": 689,
+ "p50": 77,
+ "p95": 79,
+ "max": 414
+ },
+ "samplingMediaSeconds": {
+ "count": 689,
+ "p50": 0.07662499999999994,
+ "p95": 0.0788542000000021,
+ "max": 0.0940833000000012
+ }
+ },
+ "totalVisible": 720,
+ "uniqueVisible": 720,
+ "recycled": 720,
+ "callbacks": 723,
+ "allocations": 25,
+ "reuses": 698,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 723,
+ "replies": 723,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "webkit",
+ "implementation": "candidate",
+ "rowsPerSecond": 2,
+ "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.37275,
+ "startWall": 1294,
+ "endWall": 16315,
+ "time": 15.1836874,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 24,
+ "states": {
+ "wait": 24,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 24,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 363,
+ "p50": 45,
+ "p95": 61,
+ "max": 64
+ },
+ "framesMediaSeconds": {
+ "count": 363,
+ "p50": 0.045187499999999936,
+ "p95": 0.06122919999999965,
+ "max": 0.06333330000000004
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 15.1836874,
+ "startWall": 16375,
+ "endWall": 31283,
+ "time": 29.8325622,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 48,
+ "states": {
+ "wait": 48,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 48,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 361,
+ "p50": 45,
+ "p95": 61,
+ "max": 64
+ },
+ "framesMediaSeconds": {
+ "count": 361,
+ "p50": 0.04527080000000083,
+ "p95": 0.06106250000000024,
+ "max": 0.06364589999999737
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 29.8325622,
+ "startWall": 31328,
+ "endWall": 46200,
+ "time": 44.4231129,
+ "decodedWidth": 640,
+ "visibleCount": 24,
+ "uniqueVisible": 24,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 72,
+ "states": {
+ "wait": 72,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 3,
+ "pooled": 3,
+ "uniquePool": 3,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 72,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 24,
+ "framesWallMs": {
+ "count": 365,
+ "p50": 45,
+ "p95": 61,
+ "max": 63
+ },
+ "framesMediaSeconds": {
+ "count": 365,
+ "p50": 0.044958299999997564,
+ "p95": 0.060916699999999935,
+ "max": 0.06322919999999854
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 1089,
+ "p50": 45,
+ "p95": 61,
+ "max": 337
+ },
+ "framesMediaSeconds": {
+ "count": 1089,
+ "p50": 0.045125000000000526,
+ "p95": 0.06106250000000024,
+ "max": 0.06364589999999737
+ },
+ "samplingWallMs": {
+ "count": 1089,
+ "p50": 45,
+ "p95": 61,
+ "max": 338
+ },
+ "samplingMediaSeconds": {
+ "count": 1089,
+ "p50": 0.045125000000000526,
+ "p95": 0.061062499999998465,
+ "max": 0.06362500000000182
+ }
+ },
+ "totalVisible": 72,
+ "uniqueVisible": 72,
+ "recycled": 72,
+ "callbacks": 72,
+ "allocations": 3,
+ "reuses": 69,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 72,
+ "replies": 72,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ },
+ {
+ "engine": "webkit",
+ "implementation": "candidate",
+ "rowsPerSecond": 20,
+ "sha256": "e8193aa8fae3329b3a8e435fc450726d9305e258dddea043ff3114f058516a66",
+ "cycles": [
+ {
+ "cycle": 0,
+ "base": 0.3515,
+ "startWall": 1224,
+ "endWall": 16051,
+ "time": 14.9101248,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 240,
+ "states": {
+ "wait": 240,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 22,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 240,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 217,
+ "p50": 77,
+ "p95": 80,
+ "max": 109
+ },
+ "framesMediaSeconds": {
+ "count": 217,
+ "p50": 0.07679170000000024,
+ "p95": 0.0804999999999998,
+ "max": 0.10902089999999998
+ }
+ },
+ {
+ "cycle": 1,
+ "base": 14.9101248,
+ "startWall": 16109,
+ "endWall": 31070,
+ "time": 29.5584789,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 480,
+ "states": {
+ "wait": 480,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 22,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 480,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 220,
+ "p50": 77,
+ "p95": 79,
+ "max": 93
+ },
+ "framesMediaSeconds": {
+ "count": 220,
+ "p50": 0.07683340000000172,
+ "p95": 0.07910419999999974,
+ "max": 0.0930624999999985
+ }
+ },
+ {
+ "cycle": 2,
+ "base": 29.5584789,
+ "startWall": 31135,
+ "endWall": 46123,
+ "time": 44.2043628,
+ "decodedWidth": 640,
+ "visibleCount": 240,
+ "uniqueVisible": 240,
+ "missedSampling": [],
+ "sampledNotVisible": [],
+ "queue": 720,
+ "states": {
+ "wait": 720,
+ "ready": 0,
+ "emit": 0,
+ "stop": 0
+ },
+ "nodes": 22,
+ "pooled": 22,
+ "uniquePool": 22,
+ "referenced": 0,
+ "distinctReferences": 0,
+ "uniqueStateMembers": 720,
+ "validStateMembers": true,
+ "heap": null,
+ "scheduled": 240,
+ "framesWallMs": {
+ "count": 219,
+ "p50": 77,
+ "p95": 79,
+ "max": 95
+ },
+ "framesMediaSeconds": {
+ "count": 219,
+ "p50": 0.0768333000000041,
+ "p95": 0.0792707999999962,
+ "max": 0.09527079999999444
+ }
+ }
+ ],
+ "sampleGapsIncludingLifecyclePauses": {
+ "framesWallMs": {
+ "count": 656,
+ "p50": 77,
+ "p95": 80,
+ "max": 428
+ },
+ "framesMediaSeconds": {
+ "count": 656,
+ "p50": 0.07679170000000024,
+ "p95": 0.07935409999999621,
+ "max": 0.10902089999999998
+ },
+ "samplingWallMs": {
+ "count": 656,
+ "p50": 77,
+ "p95": 80,
+ "max": 429
+ },
+ "samplingMediaSeconds": {
+ "count": 656,
+ "p50": 0.07679170000000024,
+ "p95": 0.07958329999999947,
+ "max": 0.10904169999999969
+ }
+ },
+ "totalVisible": 720,
+ "uniqueVisible": 720,
+ "recycled": 720,
+ "callbacks": 720,
+ "allocations": 22,
+ "reuses": 698,
+ "bypassedPool": 0,
+ "workers": [
+ {
+ "posts": 720,
+ "replies": 720,
+ "terminated": 1,
+ "errors": []
+ }
+ ],
+ "errors": [],
+ "destroyed": true,
+ "retainedPlayerRoots": 0
+ }
+ ],
+ "mask": [
+ {
+ "engine": "chromium",
+ "title": "published: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy",
+ "snapshots": [
+ {
+ "label": "before-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "",
+ "time": 0
+ },
+ {
+ "label": "after-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.032529
+ },
+ {
+ "label": "after-reset",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.046696
+ },
+ {
+ "label": "after-no-argument-load",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0.049324
+ },
+ {
+ "label": "after-replacement-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.065865
+ },
+ {
+ "label": "after-hide",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "0",
+ "time": 0.070047
+ },
+ {
+ "label": "after-show",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.07497
+ },
+ {
+ "label": "after-destroy-false",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-destroy-native-frames",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ }
+ ],
+ "workers": [
+ {
+ "requests": [
+ {
+ "type": "getDanmuTop",
+ "id": 1
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 2
+ }
+ ],
+ "replies": [
+ {
+ "id": 1,
+ "result": 10
+ },
+ {
+ "id": 2,
+ "result": 10
+ }
+ ],
+ "terminated": 1
+ }
+ ],
+ "visible": [
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-AFTER-LOAD"
+ ],
+ "errors": []
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy",
+ "snapshots": [
+ {
+ "label": "before-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "",
+ "time": 0
+ },
+ {
+ "label": "after-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.035365
+ },
+ {
+ "label": "after-reset",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.051809
+ },
+ {
+ "label": "after-no-argument-load",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0.054545
+ },
+ {
+ "label": "after-replacement-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.070648
+ },
+ {
+ "label": "after-hide",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "0",
+ "time": 0.076207
+ },
+ {
+ "label": "after-show",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.080349
+ },
+ {
+ "label": "after-destroy-false",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-destroy-native-frames",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ }
+ ],
+ "workers": [
+ {
+ "requests": [
+ {
+ "type": "getDanmuTop",
+ "id": 1
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 2
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 3
+ }
+ ],
+ "replies": [
+ {
+ "id": 1,
+ "result": 10
+ },
+ {
+ "id": 2,
+ "result": 10
+ },
+ {
+ "id": 3,
+ "result": 10
+ }
+ ],
+ "terminated": 1
+ }
+ ],
+ "visible": [
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-AFTER-LOAD"
+ ],
+ "errors": []
+ },
+ {
+ "engine": "firefox",
+ "title": "published: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy",
+ "snapshots": [
+ {
+ "label": "before-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "",
+ "time": 0
+ },
+ {
+ "label": "after-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.001882
+ },
+ {
+ "label": "after-reset",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.041666
+ },
+ {
+ "label": "after-no-argument-load",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0.041666
+ },
+ {
+ "label": "after-replacement-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.041666
+ },
+ {
+ "label": "after-hide",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "0",
+ "time": 0.083332
+ },
+ {
+ "label": "after-show",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.083332
+ },
+ {
+ "label": "after-destroy-false",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-destroy-native-frames",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ }
+ ],
+ "workers": [
+ {
+ "requests": [
+ {
+ "type": "getDanmuTop",
+ "id": 1
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 2
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 3
+ }
+ ],
+ "replies": [
+ {
+ "id": 1,
+ "result": 10
+ },
+ {
+ "id": 2,
+ "result": 10
+ },
+ {
+ "id": 3,
+ "result": 10
+ }
+ ],
+ "terminated": 1
+ }
+ ],
+ "visible": [
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-AFTER-LOAD"
+ ],
+ "errors": []
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy",
+ "snapshots": [
+ {
+ "label": "before-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "",
+ "time": 0
+ },
+ {
+ "label": "after-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.041666
+ },
+ {
+ "label": "after-reset",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.041666
+ },
+ {
+ "label": "after-no-argument-load",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0.041666
+ },
+ {
+ "label": "after-replacement-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.083332
+ },
+ {
+ "label": "after-hide",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "0",
+ "time": 0.083332
+ },
+ {
+ "label": "after-show",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.083332
+ },
+ {
+ "label": "after-destroy-false",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-destroy-native-frames",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ }
+ ],
+ "workers": [
+ {
+ "requests": [
+ {
+ "type": "getDanmuTop",
+ "id": 1
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 2
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 3
+ }
+ ],
+ "replies": [
+ {
+ "id": 1,
+ "result": 10
+ },
+ {
+ "id": 2,
+ "result": 10
+ },
+ {
+ "id": 3,
+ "result": 10
+ }
+ ],
+ "terminated": 1
+ }
+ ],
+ "visible": [
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-AFTER-LOAD"
+ ],
+ "errors": []
+ },
+ {
+ "engine": "webkit",
+ "title": "published: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy",
+ "snapshots": [
+ {
+ "label": "before-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "",
+ "time": 0
+ },
+ {
+ "label": "after-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.0560853
+ },
+ {
+ "label": "after-reset",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.1145099
+ },
+ {
+ "label": "after-no-argument-load",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0.1331493
+ },
+ {
+ "label": "after-replacement-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.2290091
+ },
+ {
+ "label": "after-hide",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "0",
+ "time": 0.2411342
+ },
+ {
+ "label": "after-show",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.2466298
+ },
+ {
+ "label": "after-destroy-false",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-destroy-native-frames",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ }
+ ],
+ "workers": [
+ {
+ "requests": [
+ {
+ "type": "getDanmuTop",
+ "id": 1
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 2
+ }
+ ],
+ "replies": [
+ {
+ "id": 1,
+ "result": 10
+ },
+ {
+ "id": 2,
+ "result": 10
+ }
+ ],
+ "terminated": 1
+ }
+ ],
+ "visible": [
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-AFTER-LOAD"
+ ],
+ "errors": []
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy",
+ "snapshots": [
+ {
+ "label": "before-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "",
+ "time": 0
+ },
+ {
+ "label": "after-registration",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.0547591
+ },
+ {
+ "label": "after-reset",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.1121272
+ },
+ {
+ "label": "after-no-argument-load",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0.1244461
+ },
+ {
+ "label": "after-replacement-native-emit",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.2397548
+ },
+ {
+ "label": "after-hide",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "0",
+ "time": 0.2532712
+ },
+ {
+ "label": "after-show",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 1,
+ "opacity": "1",
+ "time": 0.2585794
+ },
+ {
+ "label": "after-destroy-false",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ },
+ {
+ "label": "after-destroy-native-frames",
+ "sameLayer": true,
+ "connected": true,
+ "styles": [
+ {
+ "name": "mask-image",
+ "value": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")",
+ "priority": "",
+ "computed": "url(\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%3E%3Crect%20width%3D%22320%22%20height%3D%22360%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E\")"
+ },
+ {
+ "name": "mask-mode",
+ "value": "alpha",
+ "priority": "",
+ "computed": "alpha"
+ },
+ {
+ "name": "mask-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "mask-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ },
+ {
+ "name": "background-size",
+ "value": "contain",
+ "priority": "",
+ "computed": "contain"
+ },
+ {
+ "name": "background-repeat",
+ "value": "no-repeat",
+ "priority": "",
+ "computed": "no-repeat"
+ }
+ ],
+ "children": 0,
+ "opacity": "1",
+ "time": 0
+ }
+ ],
+ "workers": [
+ {
+ "requests": [
+ {
+ "type": "getDanmuTop",
+ "id": 1
+ },
+ {
+ "type": "getDanmuTop",
+ "id": 2
+ }
+ ],
+ "replies": [
+ {
+ "id": 1,
+ "result": 10
+ },
+ {
+ "id": 2,
+ "result": 10
+ }
+ ],
+ "terminated": 1
+ }
+ ],
+ "visible": [
+ "MASK-BOUNDARY-EMIT",
+ "MASK-BOUNDARY-AFTER-LOAD"
+ ],
+ "errors": []
+ }
+ ],
+ "resources": [
+ {
+ "engine": "chromium",
+ "title": "published: shared setting mount preserves the surviving instance and later user changes",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: invalid setting mount rolls back plugin resources while preserving the original error",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: destroy cancels pending setting send without clearing retained input or starting a lock",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "PENDING",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: destroy clears active send timer and leaves another mounted instance usable",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "LOCK",
+ "receiver": true
+ },
+ {
+ "index": 1,
+ "text": "SECOND",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: rejected setting callback retains input and original console error without an unhandled rejection",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "REJECT",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [
+ [
+ "Error emitting danmuku:",
+ "controlled setting rejection"
+ ]
+ ],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: destroy false releases actual renderer nodes while retaining the player shell",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "VISIBLE"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: replacement load removes a moved renderer node and preserves unrelated body content",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "MOVED"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "published: narrow heatmap invalid sampling stays responsive and two instances have independent gradients",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: shared setting mount preserves the surviving instance and later user changes",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: invalid setting mount rolls back plugin resources while preserving the original error",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: destroy cancels pending setting send without clearing retained input or starting a lock",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "PENDING",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: destroy clears active send timer and leaves another mounted instance usable",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "LOCK",
+ "receiver": true
+ },
+ {
+ "index": 1,
+ "text": "SECOND",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: rejected setting callback retains input and original console error without an unhandled rejection",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "REJECT",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [
+ [
+ "Error emitting danmuku:",
+ "controlled setting rejection"
+ ]
+ ],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: destroy false releases actual renderer nodes while retaining the player shell",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "VISIBLE"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: replacement load removes a moved renderer node and preserves unrelated body content",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "MOVED"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "chromium",
+ "title": "candidate: narrow heatmap invalid sampling stays responsive and two instances have independent gradients",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: shared setting mount preserves the surviving instance and later user changes",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: invalid setting mount rolls back plugin resources while preserving the original error",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: destroy cancels pending setting send without clearing retained input or starting a lock",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "PENDING",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: destroy clears active send timer and leaves another mounted instance usable",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "LOCK",
+ "receiver": true
+ },
+ {
+ "index": 1,
+ "text": "SECOND",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: rejected setting callback retains input and original console error without an unhandled rejection",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "REJECT",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [
+ [
+ "Error emitting danmuku:",
+ "controlled setting rejection"
+ ]
+ ],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: destroy false releases actual renderer nodes while retaining the player shell",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "VISIBLE"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: replacement load removes a moved renderer node and preserves unrelated body content",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "MOVED"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "published: narrow heatmap invalid sampling stays responsive and two instances have independent gradients",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: shared setting mount preserves the surviving instance and later user changes",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: invalid setting mount rolls back plugin resources while preserving the original error",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: destroy cancels pending setting send without clearing retained input or starting a lock",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "PENDING",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: destroy clears active send timer and leaves another mounted instance usable",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "LOCK",
+ "receiver": true
+ },
+ {
+ "index": 1,
+ "text": "SECOND",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: rejected setting callback retains input and original console error without an unhandled rejection",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "REJECT",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [
+ [
+ "Error emitting danmuku:",
+ "controlled setting rejection"
+ ]
+ ],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: destroy false releases actual renderer nodes while retaining the player shell",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "VISIBLE"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: replacement load removes a moved renderer node and preserves unrelated body content",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "MOVED"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "firefox",
+ "title": "candidate: narrow heatmap invalid sampling stays responsive and two instances have independent gradients",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: shared setting mount preserves the surviving instance and later user changes",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: invalid setting mount rolls back plugin resources while preserving the original error",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: destroy cancels pending setting send without clearing retained input or starting a lock",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "PENDING",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: destroy clears active send timer and leaves another mounted instance usable",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "LOCK",
+ "receiver": true
+ },
+ {
+ "index": 1,
+ "text": "SECOND",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: rejected setting callback retains input and original console error without an unhandled rejection",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "REJECT",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [
+ [
+ "Error emitting danmuku:",
+ "controlled setting rejection"
+ ]
+ ],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: destroy false releases actual renderer nodes while retaining the player shell",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "VISIBLE"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: replacement load removes a moved renderer node and preserves unrelated body content",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "MOVED"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "published: narrow heatmap invalid sampling stays responsive and two instances have independent gradients",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: shared setting mount preserves the surviving instance and later user changes",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: invalid setting mount rolls back plugin resources while preserving the original error",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: destroy cancels pending setting send without clearing retained input or starting a lock",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "PENDING",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: destroy clears active send timer and leaves another mounted instance usable",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "LOCK",
+ "receiver": true
+ },
+ {
+ "index": 1,
+ "text": "SECOND",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: rejected setting callback retains input and original console error without an unhandled rejection",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [
+ {
+ "index": 0,
+ "text": "REJECT",
+ "receiver": true
+ }
+ ],
+ "messages": [],
+ "errors": [
+ [
+ "Error emitting danmuku:",
+ "controlled setting rejection"
+ ]
+ ],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: destroy false releases actual renderer nodes while retaining the player shell",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "VISIBLE"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: replacement load removes a moved renderer node and preserves unrelated body content",
+ "workers": [
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [
+ "MOVED"
+ ],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ },
+ {
+ "engine": "webkit",
+ "title": "candidate: narrow heatmap invalid sampling stays responsive and two instances have independent gradients",
+ "workers": [
+ {
+ "terminated": 1
+ },
+ {
+ "terminated": 1
+ }
+ ],
+ "sends": [],
+ "messages": [],
+ "errors": [],
+ "retainedSettings": 0,
+ "timers": 0
+ }
+ ],
+ "checks": [
+ {
+ "file": "refactor/.cache/danmuku07-lint.log",
+ "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ {
+ "file": "refactor/.cache/danmuku07-impact.log",
+ "sha256": "a273a996c268b4ad09d1a4fed9b75ede1417e499f26ccbed7f134d00209f5c3e"
+ }
+ ],
+ "scope": "Candidate core with fixed published/candidate plugins at 2 and 20 rows per second, three native 14-second append/play/pause cycles. Source candidate, synchronous true callbacks, antiOverlap false. Hard candidate delivery/once/recycle/state ownership/actual node reuse checks. Two-core CSS root-mask boundary plus existing resource suite. Not model inference, device equivalence, unbounded soak or heap leak proof.",
+ "timingDiagnosis": {
+ "evidence": "refactor/baselines/danmuku-frame-sampling-validation.json",
+ "resolvedDefects": [
+ "PKG-DANMUKU-11",
+ "PKG-DANMUKU-12"
+ ],
+ "unchangedBoundary": "An 800ms blocked main thread cannot sample crossed timestamps under the historical +/-0.1-second rule. No invisible catchup or seeded readiness is used in the load suite."
+ },
+ "failures": [
+ {
+ "file": "refactor/.cache/danmuku07-stability-first.json",
+ "sha256": "89fbdf1c241eb8f855dcd7b69dc59cd3e6047aedaa3b6d73f8cd83764f4b1a38"
+ }
+ ],
+ "calibration": "First two Chromium cases failed only because the test wrongly expected load(rows) to replace. Source contract confirmed append; queue expectation changed to cumulative count while each-cycle visible count stayed exact. Initial corrected 12-case run passed, then independent review added actual node identity reuse, per-item state membership, once-only final visible/recycle and nonempty Worker assertions for this final run.",
+ "reusedEvidence": [
+ "refactor/baselines/danmuku-frame-sampling-validation.json",
+ "refactor/baselines/danmuku-lifetime-validation.json",
+ "refactor/baselines/danmuku-heatmap-density-validation.json"
+ ],
+ "reuseReason": "No runtime or declaration change after PKG-DANMUKU-12. Its source/modern/legacy tests cover asynchronous serial dispatch, cancellation, geometry and visible lifetime; this task adds native load/resource/CSS evidence rather than claiming those paths were rerun by the load suite.",
+ "fingerprints": [
+ {
+ "file": "test/browser/danmuku-stability.spec.js",
+ "sha256": "2778330a1a907c6d710ac8d47004c36e1527c94817644f1419f9ea71340e084e"
+ },
+ {
+ "file": "test/browser/danmuku-mask-boundary.spec.js",
+ "sha256": "4220fa681f8d577ac666d02807f60337fb2a71bfc27cd1e1b0c47807215e1bdc"
+ },
+ {
+ "file": "test/browser/danmuku-resources.spec.js",
+ "sha256": "f0d09e962cb422a66bd644c52268aff8f288606ae9c93676fa979539743f9c6b"
+ },
+ {
+ "file": "packages/artplayer-plugin-danmuku/src/scheduler.ts",
+ "sha256": "8b5623a34e81253f08633c0240cf632e23f890b76ebfe96e21da23597cd35447"
+ },
+ {
+ "file": "packages/artplayer-plugin-danmuku/src/scheduling-buffer.ts",
+ "sha256": "0a7eaf5229adcc74a8d9814fbc9a61cb3990045b3e99ac4ad9dc3f65fb9aab2e"
+ },
+ {
+ "file": "packages/artplayer-plugin-danmuku/src/renderer.ts",
+ "sha256": "6ac4b1991c6cb683353a811f41b6ca025401029720cbcadaff120616ca936cdf"
+ },
+ {
+ "file": "packages/artplayer-plugin-danmuku-mask/src/index.js",
+ "sha256": "2397900688f86bc74bc86a4e870f69478a651bd8df02bba543cdab832773fd6e"
+ }
+ ],
+ "remaining": [
+ "PKG-DANMUKU-08 full combinations",
+ "PKG-DANMUKU-09 final distribution/docs",
+ "Mask lifecycle/TS/model migration and genuine model integration",
+ "Device and release review gates"
+ ]
+}
diff --git a/refactor/changes/2026-09-13-PKG-DANMUKU-07-stability.md b/refactor/changes/2026-09-13-PKG-DANMUKU-07-stability.md
new file mode 100644
index 000000000..3a87f7cef
--- /dev/null
+++ b/refactor/changes/2026-09-13-PKG-DANMUKU-07-stability.md
@@ -0,0 +1,66 @@
+# PKG-DANMUKU-07 弹幕稳定性与共享层边界
+
+已完成本任务限定的验收,任务及提交状态以tasks.json和Git为准。此项对12后的生产
+实现增加原生负载和资源验收,没有改变运行时、声明、依赖、版本或构建内容。
+
+## 验收范围
+
+- 候选核心中比较固定npm5.3.0插件与候选源码,三引擎,每秒2和20条,各三轮
+ 14秒真实媒体播放。每轮追加12秒的时间戳序列,三轮总计72/720条;其余时间
+ 让弹幕自然显示和到期。保留真实RAF、视频时钟、Worker与原始readys getter。
+- 候选逐项检查采样/显示无丢失,三轮总显示和回收均恰好一次;队列追加语义、
+ 每条对象只属于一个对应状态池、空闲池唯一性、根层节点和空闲池一致均受断言保护。
+ 包装原始节点getter只记录身份,确认实际重复使用旧节点,并且有空闲节点时
+ 不绕过池分配新节点;Worker必须存在且唯一,正常请求全部回复,销毁恰好一次。
+- 旧插件结果保留为对照观察,没有把其可能的历史缺陷豁免用于候选断言。
+ 每轮帧间隔单独统计;包含暂停/加载转换的总采样间隔另列,不能当纯播放卡顿。
+ 可选performance.memory是未强制GC的读数,不能证明泄漏或作跨引擎内存排名。
+- 两核心、三引擎运行已有资源用例:共享挂载、初始化回滚、发送取消/锁、原始
+ 错误、destroy(false)、替换加载移除被移动的节点、热图实例隔离。
+- 新增两核心的CSS mask边界用例:注册前就取得核心根层,以固定内联SVG mask
+ 验证emit/reset/无参替换load/hide/show/destroy(false)中的层引用和样式保持,
+ 销毁后两帧没有晚请求和新子节点。此用例设置资源测试的ready前置状态、采用
+ 原生0.25播放速率,不能当时间戳负载证据;负载用例没有这些设置。
+
+## 问题处置与兼容性
+
+早期原生时间窗口诊断区分了两个来源:800ms主线程完全阻塞,及600ms用户异步
+回调使旧调度停止采样。11独立修复隐藏Worker等待吞掉显示寿命;12独立修复异步
+放置期间的采样和到期维护。07继续检查这些修复后的实际负载及资源状态。
+没有把公开±0.1秒窗口改成无限追赶,因此完全阻塞时未被采样的时间点仍可错过。
+
+本轮首个测试版本错误地把`load(rows)`当作替换,第二轮队列断言收到48/480而
+错误预期24/240。核实原实现后修正累计队列预期,当轮显示数仍精确24/240;没有
+修改生产语义。初步12项通过后,经独立审查补足Worker非空、节点身份复用、
+逐条状态归属和跨轮恰好一次的断言,最终需按补强后的文件重新验证。
+
+Mask仅依赖核心提供的video/弹幕根层及ready/destroy,不读取弹幕队列、Owner
+或插件事件。旧契约文档误称根层由Danmuku建立,已依据核心模板纠正并注明日期。
+固定发布归档和生产Mask源码未改。Mask自身晚推理复活RAF、模型dispose、并发
+start、模型和完整组合问题仍由Mask迁移任务处理,不能从本CSS测试判定通过。
+
+## 维护与重跑
+
+```sh
+yarn test:browser test/browser/danmuku-stability.spec.js test/browser/danmuku-mask-boundary.spec.js test/browser/danmuku-resources.spec.js --workers=2
+```
+
+负载测试的90秒单例deadline来自三轮42秒媒体预算及设置/销毁开销;没有扩大
+已有短用例超时。每次运行必须等待进程终态,归档report/results,再运行另一格式。
+正常来源是当前源码UMD;两个新用例均支持ARTPLAYER_DANMUKU_ARTIFACT。
+
+包内ARCHITECTURE.md与refactor/danmuku-stability.md记录根层归属、诊断及限制。
+07未修改生产,因此复用12已记录的264项源码/136项产物单测、严格类型/构建,及
+其异步/几何/生命周期验证;不声称这些由本次持续负载套件重新完成。
+08完整组合、09最终分发、真实Mask模型/设备以及全项目发布复盘继续保留。
+回退本任务只撤销测试和文档,不应回退11/12已交付修复。
+
+## 最终结果
+
+补强后的66项浏览器检查全部通过(12项负载、6项CSS边界、48项资源),0重试、
+0跳过。每个负载用例完成三轮42秒原生媒体推进,候选两档各72/720条均完整且
+只显示/回收一次。精确节点复用、堆读数和帧间隔见
+[机器证据](../baselines/danmuku-stability-validation.json)。
+新测试lint通过;影响分析检查通过,保留Danmuku/Mask组合验证边,仅纠正其
+“Danmuku创建根层”的错误原因,不降低CI范围。测试由现有Playwright目录自动发现。
+未运行远端CI、未推送或发布。
diff --git a/refactor/danmuku-stability.md b/refactor/danmuku-stability.md
new file mode 100644
index 000000000..6f48162c4
--- /dev/null
+++ b/refactor/danmuku-stability.md
@@ -0,0 +1,70 @@
+# PKG-DANMUKU-07 稳定性工作记录
+
+本任务已在12后的运行时完成下述限定范围验收,任务与提交状态以tasks.json及Git为准。
+06类型检查、11/12修复与本任务证据分别维护;真实模型、完整组合和发布验收仍待后续任务。
+
+## 已执行的时间窗口诊断
+
+`test/browser/danmuku-timing-diagnostic.spec.js`在候选核心中比较实际npm5.3.0插件与
+06候选源码,使用本地90秒视频的短片段、原生RAF/媒体时钟和真实Worker。独立RAF
+观察与实际readys getter采样分别记录;getter只包装读取,不修改返回数组或状态。
+每例3条弹幕,后置sentinel证明间隔后仍能正常发送。12项诊断通过意味着取证完成,
+不代表漏掉弹幕的结果可以作为稳定性通过。
+
+| 场景 | Chromium | Firefox | Windows WebKit | 新旧共同结果 |
+| --- | --- | --- | --- | --- |
+| 注入800ms主线程工作 | 最大媒体帧间隔约800ms | 约777–809ms | 约838–856ms | 前两条未进入任何readys采样,sentinel显示 |
+| beforeVisible等待600ms | 原生帧间隔约19–21ms,采样间隔616–618ms | 帧44ms,采样583–609ms | 帧63–64ms,采样622–647ms | 第一条与sentinel显示,中间条未采样 |
+
+这解释了两种不同来源:前者浏览器主线程无法及时调度,后者浏览器仍在出帧,但
+插件等待当前异步准备完成而不再读取新的候选窗口。±0.1秒和串行回调都有明确
+历史语义;后续方案必须比较seek、hide/show、stop/start和false重试边界,不能
+直接改成无限追赶或并行回调。当前不据此声称全部真实负载问题已解决。
+
+报告位于refactor/.cache/danmuku07-timing-diagnostic.json,日志及附件保留同名前缀。
+候选是11计时修复之前的06源码,具体构建SHA在每项danmuku-timing-observation中;
+后续变更需说明哪些观察仍适用,不把旧报告冒充新提交的验证。
+
+## 当前下一步
+
+以下为本轮执行入口的历史清单,现已通过最终66项原生用例落实本任务范围。
+下一实施阶段为08组合或其他已就绪包任务;09分发和真实Mask模型/设备仍不能据此关闭。
+
+1. 11计时修复和12采样修复已分别提交并核验;当前HEAD为
+ `4f559cb31d6b69a37439c6db2d32ca28ae5c78f3`,恢复本任务。
+ 12源码/main/legacy各102项浏览器通过,慢回调中间行已恢复;CPU完全阻塞
+ 的未采样窗口仍保留。见[12证据](baselines/danmuku-frame-sampling-validation.json)。
+2. 对实际持续播放记录scheduled、readys、callback、placed、visible、recycled及
+ 原生RAF/媒体间隔,区分false、拒绝、轨道满、取消和错过采样。
+3. 比较正常密度、密集队列和连续生命周期后的节点池、Worker、监听器与计时器。
+ 已有受控三小时快进只证明离散状态,不是真实三小时播放或内存测量。
+4. 根据证据决定是否需要兼容内部修复,并为每个独立修复保留任务和commit。
+5. 明确Mask可依赖的当前队列/DOM/事件边界,再交付07验收与后续08组合矩阵。
+
+不增加任意弹幕上限,不通过修改媒体时钟、预置ready或放宽断言伪造负载通过。
+
+## 本轮新增的持续播放与边界取证
+
+`test/browser/danmuku-stability.spec.js` 使用候选核心、实际npm5.3.0/候选插件、
+原生视频/RAF/Worker,每秒2或20条,各三轮14秒实际媒体推进。每轮追加12秒
+的时间戳序列,余下时间用于自然显示和回收;逐条记录采样/显示/回收,同时记录
+状态池、节点/空闲池、真实帧和可选未强制GC的堆内存读数。不是三小时耐久测试,
+也不把不同浏览器的performance.memory当作可比的泄漏证明。
+
+首轮Chromium两个用例因测试误把`load(rows)`当作替换,在第二轮队列断言失败:
+收到48/480,错误预期24/240。核对运行实现后按既有追加契约修正为累计队列数,
+当轮显示数量仍严格断言24/240;没有改变生产API。失败报告与trace保留在
+`refactor/.cache/danmuku07-stability-first.json`及同前缀results中。
+
+Mask静态审查已确认其直接依赖只有核心video/root层/ready/destroy,未读取弹幕
+队列或Owner。已纠正旧契约对根层创建归属的错误描述;核心模板及节点绑定为依据。
+后续CSS mask边界测试明确不加载真实模型,不代替Mask03/05的候选生命周期与组合验收。
+
+最终补强了非空Worker、实际节点复用、每条状态归属和跨轮显示/回收恰好一次检查。
+12负载、6共享mask层、48资源测试共66项在三引擎全部通过,0重试/跳过。
+见[变更记录](changes/2026-09-13-PKG-DANMUKU-07-stability.md)和
+[机器证据](baselines/danmuku-stability-validation.json)。
+
+本次候选每秒2条用例三轮72条只分配3个节点、实际复用69次;每秒20条三轮720条
+分配21–22个节点、复用698–699次。旧版对应分配6及24–25个节点。两者该正常
+同步回调负载下都完整显示;差异是本次原生样本观察,不是通用吞吐或长期内存承诺。
diff --git a/refactor/impact-policy.json b/refactor/impact-policy.json
index 6e06fb209..114f40621 100644
--- a/refactor/impact-policy.json
+++ b/refactor/impact-policy.json
@@ -121,7 +121,7 @@
{
"dependency": "artplayer-plugin-danmuku",
"consumer": "artplayer-plugin-danmuku-mask",
- "reason": "Mask renders into the $danmuku element supplied by the danmuku plugin",
+ "reason": "Mask and Danmuku share the core-owned $danmuku layer; retain combination validation for root identity, styles and lifecycle",
"evidence": [
"packages/artplayer-plugin-danmuku-mask/src/index.js",
"docs/assets/example/danmuku.mask.js"
diff --git a/refactor/plan.md b/refactor/plan.md
index 5aced626f..e3eee6575 100644
--- a/refactor/plan.md
+++ b/refactor/plan.md
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 231 项,范围 22 个包及工作区/示例。
-状态:todo 68 / doing 15 / blocked 0 / done 148 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
+状态:todo 68 / doing 14 / blocked 0 / done 149 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -315,7 +315,7 @@
| PKG-DANMUKU-04 | artplayer-plugin-danmuku
整理时钟、队列与轨道调度 | PKG-DANMUKU-03, CORE-10 | danmuku 调度器和确定性时钟测试 | seek/暂停/倍率/长时间运行无顺序和碰撞回归 | H | done |
| PKG-DANMUKU-05 | artplayer-plugin-danmuku
整理 DOM 渲染、设置、热力图与 worker | PKG-DANMUKU-04, CORE-14, CORE-18 | renderer/setting/heatmap/worker 职责及资源归属 | mount/icons/设置和 worker 协议保持,销毁无后台工作 | H | done |
| PKG-DANMUKU-06 | artplayer-plugin-danmuku
迁移 TS 与公开声明 | PKG-DANMUKU-05, ENG-04, ENG-06 | 自有模块、worker 消息、option/item/result 类型 | 旧参数、扩展字段和事件消费通过,vendored 边界清楚 | H | done |
-| PKG-DANMUKU-07 | artplayer-plugin-danmuku
弹幕能力稳定性验收 | PKG-DANMUKU-06, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12 | 负载/渲染/资源对比及 mask 可依赖的稳定边界 | 在试点核心中旧插件 API 与关键帧路径通过 | H | doing |
+| PKG-DANMUKU-07 | artplayer-plugin-danmuku
弹幕能力稳定性验收 | PKG-DANMUKU-06, PKG-DANMUKU-10, PKG-DANMUKU-11, PKG-DANMUKU-12 | 负载/渲染/资源对比及 mask 可依赖的稳定边界 | 在试点核心中旧插件 API 与关键帧路径通过 | H | done |
| PKG-DANMUKU-08 | artplayer-plugin-danmuku
完成新旧核心与组合验收 | PKG-DANMUKU-07, CORE-22 | 最终核心/旧核心、mask/fullscreen/PiP 组合报告 | 性能无未解释退化,反复装卸无累计资源 | H | todo |
| PKG-DANMUKU-09 | artplayer-plugin-danmuku
完成分发、示例与文档 | PKG-DANMUKU-08, ENG-07 | danmuku.js、README、声明、worker 与产物 | tarball 和静态 icons 等旧调用通过,有独立回退版本 | H | todo |
| PKG-DANMUKU-10 | artplayer-plugin-danmuku
修复 issue958 密集热力图过高与曲线裁平 | PKG-DANMUKU-05 | 自动密度缩放与曲线边界、历史自定义坐标兼容及真实浏览器红绿证据 | 16000条三种分布在两核心三引擎和source/main/legacy不遮挡;显式轴和自定义points保持旧解释,有单独commit | M | done |
@@ -562,6 +562,7 @@
- PKG-DANMUKU-04: [记录](changes/2026-09-13-PKG-DANMUKU-04-scheduler.md) [记录](baselines/danmuku-scheduler-validation.json)
- PKG-DANMUKU-05: [记录](changes/2026-09-13-PKG-DANMUKU-05-resources.md) [记录](baselines/danmuku-resources-validation.json)
- PKG-DANMUKU-06: [记录](changes/2026-09-13-PKG-DANMUKU-06-types.md) [记录](baselines/danmuku-types-validation.json)
+- PKG-DANMUKU-07: [记录](changes/2026-09-13-PKG-DANMUKU-07-stability.md) [记录](baselines/danmuku-stability-validation.json) [记录](danmuku-stability.md)
- PKG-CANVAS-01: [记录](changes/2026-09-12-PKG-CANVAS-01-contract.md) [记录](baselines/canvas-contract.md) [记录](baselines/canvas-release.json) [记录](canvas-validation.md) [记录](baselines/canvas-contract-validation.json)
- PKG-CANVAS-02: [记录](changes/2026-09-12-PKG-CANVAS-02-tests.md) [记录](baselines/canvas-behavior-validation.json) [记录](canvas-validation.md)
- PKG-CANVAS-03: [记录](changes/2026-09-12-PKG-CANVAS-03-lifecycle.md) [记录](baselines/canvas-lifecycle-validation.json) [记录](canvas-validation.md)
diff --git a/refactor/progress.md b/refactor/progress.md
index f56c5902e..f7d7ed1cb 100644
--- a/refactor/progress.md
+++ b/refactor/progress.md
@@ -1,5 +1,19 @@
# 进度与证据
+## PKG-DANMUKU-07 弹幕稳定性阶段验收完成
+
+12后的源码在三引擎完成新旧插件两档负载对照,每例三轮42秒原生播放;候选
+72/720条全部采样、显示并回收一次,真实节点复用、状态池唯一归属和Worker清理通过。
+两核心共享CSS mask根层与已有资源回归通过;最终12+6+48共66项,0重试/跳过。
+首轮错误测试把load(rows)当替换,修正为历史追加契约并保留失败报告;独立审查
+补足复用与跨轮重复断言。Mask不依赖队列,根层属于核心;纠正文档和影响映射原因,
+保留组合CI范围。lint及影响检查通过,没有生产/声明/依赖变化,复用12的相关验证。
+见[变更](changes/2026-09-13-PKG-DANMUKU-07-stability.md)和
+[证据](baselines/danmuku-stability-validation.json)。DANMUKU-LOAD-01按已解释来源及
+11/12独立修复闭环;CPU阻塞下旧窗口不追赶的边界明确保留,不声称无条件无漏弹幕。
+231项:149 done、14 doing、68 todo。08完整组合、09分发、真实Mask模型和设备/
+发布复盘继续;独立本地提交,不推送、不发布。
+
## PKG-DANMUKU-12 持续采样与串行放置完成
异步beforeVisible/Worker等待期间继续原生RAF采样和可见寿命维护,以内部身份
diff --git a/refactor/risk-table.md b/refactor/risk-table.md
index 8e3dfda2a..dc9d17727 100644
--- a/refactor/risk-table.md
+++ b/refactor/risk-table.md
@@ -237,7 +237,7 @@
| DANMUKU-SOURCE-01 | open / 已复现 | Danmuku registry Git associations differ from releases and static icon provenance remains incomplete | PKG-DANMUKU-09 |
| DANMUKU-TRACK-01 | resolved / 已复现 | Native simultaneous fixed Danmuku comments can overlap with duplicate start loops and repeated Worker IDs | PKG-DANMUKU-04, PKG-DANMUKU-05, PKG-DANMUKU-07 |
| DANMUKU-INPUT-02 | resolved / 已复现 | Intermediate explicit-zero correction regressed accepted NaN timestamp fallback | PKG-DANMUKU-04 |
-| DANMUKU-LOAD-01 | open / 待取证 | Native lifecycle fixtures sometimes miss timestamp eligibility during concurrent workload; real frame/window behavior needs load evidence | PKG-DANMUKU-07 |
+| DANMUKU-LOAD-01 | resolved / 已复现 | Native lifecycle fixtures sometimes miss timestamp eligibility during concurrent workload; real frame/window behavior needs load evidence | PKG-DANMUKU-07 |
| DANMUKU-HEATMAP-02 | resolved / 已复现 | Issue958 dense automatic heatmaps exceed the fixed Y domain and flatten across video | PKG-DANMUKU-10 |
| DANMUKU-TIMING-01 | resolved / 已复现 | Hidden Worker wait is deducted from visible lifetime and can recycle a comment immediately after visible | PKG-DANMUKU-11 |
| DANMUKU-SAMPLING-01 | resolved / 已复现 | Serial asynchronous placement stops native frame eligibility sampling and delays existing visible expiry | PKG-DANMUKU-12 |
diff --git a/refactor/risks.json b/refactor/risks.json
index d53f8b11b..05a61fe3c 100644
--- a/refactor/risks.json
+++ b/refactor/risks.json
@@ -5290,18 +5290,27 @@
{
"id": "DANMUKU-LOAD-01",
"title": "Native lifecycle fixtures sometimes miss timestamp eligibility during concurrent workload; real frame/window behavior needs load evidence",
- "confirmation": "unverified",
- "status": "open",
+ "confirmation": "reproduced",
+ "status": "resolved",
"owners": [
"PKG-DANMUKU-07"
],
"evidence": [
"refactor/changes/2026-09-13-PKG-DANMUKU-05-resources.md",
"refactor/baselines/danmuku-resources-validation.json",
- "test/browser/danmuku-scheduler.spec.js"
+ "test/browser/danmuku-scheduler.spec.js",
+ "refactor/baselines/danmuku-stability-validation.json",
+ "refactor/baselines/danmuku-frame-sampling-validation.json"
],
"compatibleResolution": "Capture native RAF/media-time gaps and scheduled/eligible/visible item counts under realistic load before deciding whether the old plus/minus 0.1 second eligibility rule needs a compatible correction.",
- "closureCriteria": "Real load runs explain missing scheduled items with frame and media evidence, and any confirmed implementation defect has a regression and compatible fix; seeding ready in lifecycle fixtures is not closure evidence."
+ "closureCriteria": "Real load runs explain missing scheduled items with frame and media evidence, and any confirmed implementation defect has a regression and compatible fix; seeding ready in lifecycle fixtures is not closure evidence.",
+ "resolutionEvidence": [
+ "refactor/baselines/danmuku-stability-validation.json",
+ "refactor/changes/2026-09-13-PKG-DANMUKU-07-stability.md",
+ "refactor/baselines/danmuku-frame-sampling-validation.json",
+ "refactor/baselines/danmuku-lifetime-validation.json"
+ ],
+ "resolutionRationale": "Native timing evidence distinguishes unobserved CPU-blocked windows from asynchronous scheduler starvation. Tasks 11/12 fix the reproduced implementation defects. Final three-engine real-load runs keep candidate scheduled rows observed/displayed/recycled exactly once, with actual node reuse and state/Worker ownership; unchanged historical CPU-gap semantics and full model/device/release scope remain explicit."
},
{
"id": "DANMUKU-HEATMAP-02",
diff --git a/refactor/tasks.json b/refactor/tasks.json
index 4cb4b9d21..73ff89664 100644
--- a/refactor/tasks.json
+++ b/refactor/tasks.json
@@ -3384,11 +3384,15 @@
"PKG-DANMUKU-11",
"PKG-DANMUKU-12"
],
- "status": "doing",
+ "status": "done",
"risk": "H",
"deliverable": "负载/渲染/资源对比及 mask 可依赖的稳定边界",
"acceptance": "在试点核心中旧插件 API 与关键帧路径通过",
- "evidence": []
+ "evidence": [
+ "changes/2026-09-13-PKG-DANMUKU-07-stability.md",
+ "baselines/danmuku-stability-validation.json",
+ "danmuku-stability.md"
+ ]
},
{
"id": "PKG-DANMUKU-08",
diff --git a/test/browser/README.md b/test/browser/README.md
index 792449247..b83aa0ad3 100644
--- a/test/browser/README.md
+++ b/test/browser/README.md
@@ -147,3 +147,14 @@ rows and serial callbacks; the fixed published baseline retains its missing midd
row. CPU-block observations remain diagnostic, not no-loss acceptance. Both it and
`danmuku-lifetime.spec.js` accept the same artifact override. The latter verifies
the full visible lifetime after a controlled delay to an actual Worker request.
+
+`danmuku-stability.spec.js` runs three native 14-second media cycles at 2 or 20
+rows per second, appending through the public load(rows) contract. The candidate
+must deliver and recycle every row once, preserve state membership and reuse
+actual node identities. Its 90-second per-case deadline budgets the 42 seconds
+of media plus setup/teardown; it is not a relaxation of other tests. Heap readings
+remain observations. No media/RAF clock is replaced or ready state seeded here.
+`danmuku-mask-boundary.spec.js` verifies the core-owned root and external CSS mask
+across commands and destroy(false), with actual video and placement Worker. It
+uses explicit ready rows for resource setup and a fixed SVG mask; it does not
+load the Mask SDK/model or provide timestamp-delivery evidence.
diff --git a/test/browser/danmuku-mask-boundary.spec.js b/test/browser/danmuku-mask-boundary.spec.js
new file mode 100644
index 000000000..756802247
--- /dev/null
+++ b/test/browser/danmuku-mask-boundary.spec.js
@@ -0,0 +1,176 @@
+import fs from 'node:fs'
+import process from 'node:process'
+import { hash } from '../../refactor/scripts/releases.mjs'
+import { compilePackage } from '../helpers/load.js'
+import { expect, test } from './fixtures.js'
+
+let candidate
+test.beforeAll(async () => {
+ candidate = process.env.ARTPLAYER_DANMUKU_ARTIFACT
+ ? fs.readFileSync(process.env.ARTPLAYER_DANMUKU_ARTIFACT, 'utf8')
+ : await compilePackage('artplayer-plugin-danmuku', 'umd')
+})
+
+async function setup(page, core, testInfo) {
+ const external = []
+ const origin = new URL(testInfo.project.use.baseURL).origin
+ await page.route('**/*', (route) => {
+ if (new URL(route.request().url()).origin !== origin) {
+ external.push(route.request().url())
+ return route.abort()
+ }
+ return route.continue()
+ })
+ await page.goto(`/test/player.html?core=${core}`)
+ await page.addScriptTag({ content: candidate })
+ await page.evaluate(() => {
+ window.maskBoundaryEvidence = { snapshots: [], workers: [], visible: [], errors: [] }
+ const NativeWorker = window.Worker
+ window.Worker = class extends NativeWorker {
+ constructor(url, options) {
+ super(url, options)
+ this.observation = { requests: [], replies: [], terminated: 0 }
+ window.maskBoundaryEvidence.workers.push(this.observation)
+ this.addEventListener('message', ({ data }) => this.observation.replies.push({ id: data.id, result: data.result ?? null }))
+ }
+
+ postMessage(message, ...args) {
+ this.observation.requests.push({ type: message.type, id: message.id })
+ return super.postMessage(message, ...args)
+ }
+
+ terminate() {
+ this.observation.terminated++
+ return super.terminate()
+ }
+ }
+ window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true })
+ window.maskBoundaryLayer = window.art.template.$danmuku
+ const layer = window.maskBoundaryLayer
+ // Fixed CSS input tests Danmuku's shared-layer contract. No Mask plugin,
+ // model, TensorFlow backend or segmentation output is loaded or simulated.
+ const svg = ''
+ layer.style.maskImage = `url("data:image/svg+xml,${encodeURIComponent(svg)}")`
+ Object.assign(layer.style, { maskMode: 'alpha', maskSize: 'contain', maskRepeat: 'no-repeat', backgroundSize: 'contain', backgroundRepeat: 'no-repeat' })
+ window.maskBoundarySnapshot = (label) => {
+ const properties = ['mask-image', 'mask-mode', 'mask-size', 'mask-repeat', 'background-size', 'background-repeat']
+ const computed = getComputedStyle(layer)
+ const snapshot = {
+ label,
+ sameLayer: window.art.template.$danmuku === layer,
+ connected: layer.isConnected,
+ styles: properties.map(name => ({ name, value: layer.style.getPropertyValue(name), priority: layer.style.getPropertyPriority(name), computed: computed.getPropertyValue(name) })),
+ children: layer.children.length,
+ opacity: layer.style.opacity,
+ time: window.art.currentTime,
+ }
+ window.maskBoundaryEvidence.snapshots.push(snapshot)
+ return snapshot
+ }
+ window.maskBoundaryBase = window.maskBoundarySnapshot('before-registration')
+ window.art.on('artplayerPluginDanmuku:visible', item => window.maskBoundaryEvidence.visible.push(item.id))
+ window.art.on('artplayerPluginDanmuku:error', error => window.maskBoundaryEvidence.errors.push(String(error)))
+ window.art.plugins.add(window.artplayerPluginDanmuku({ danmuku: [], heatmap: false, speed: 8, margin: [10, 10], fontSize: 20 }))
+ window.maskBoundaryPlugin = window.art.plugins.artplayerPluginDanmuku
+ document.querySelector('#play').onclick = () => window.art.play()
+ })
+ await expect.poll(() => page.evaluate(() => window.art.isReady && window.art.template.$video.videoWidth > 0)).toBe(true)
+ // Real slow playback leaves room for lifecycle checks on the finite fixture.
+ await page.evaluate(() => window.art.playbackRate = 0.25)
+ await testInfo.attach('danmuku-mask-boundary-inputs', {
+ contentType: 'application/json',
+ body: JSON.stringify({ core, artifact: process.env.ARTPLAYER_DANMUKU_ARTIFACT || 'source UMD', sha256: hash(candidate), media: '/test/pattern.mp4', scope: 'Shared root-layer identity and CSS preservation with fixed inline SVG mask; native video, DOM, RAF and placement Worker. No Mask SDK/model/end-to-end acceptance. Eligible rows are explicit resource-test preconditions, not timestamp-delivery evidence.' }),
+ })
+ return external
+}
+
+async function assertLayer(page, label) {
+ const { baseline, snapshot } = await page.evaluate(label => ({ baseline: window.maskBoundaryBase, snapshot: window.maskBoundarySnapshot(label) }), label)
+ expect(snapshot.sameLayer, label).toBe(true)
+ expect(snapshot.connected, label).toBe(true)
+ expect(snapshot.styles, label).toEqual(baseline.styles)
+ return snapshot
+}
+
+async function renderRow(page, id) {
+ await page.evaluate(async (id) => {
+ const owner = await window.maskBoundaryPlugin.emit({ id, text: id, mode: 1, time: 0 })
+ // Establish eligibility, then require actual placement Worker and visible DOM.
+ owner.setState(owner.queue[owner.queue.length - 1], 'ready')
+ window.maskBoundaryOwner = owner
+ }, id)
+ await page.click('#play')
+ await expect.poll(() => page.evaluate(id => window.maskBoundaryEvidence.visible.includes(id), id)).toBe(true)
+ await expect.poll(() => page.evaluate((id) => {
+ const node = [...window.maskBoundaryLayer.children].find(node => node.dataset.id === id)
+ if (!node)
+ return false
+ const rect = node.getBoundingClientRect()
+ return node.dataset.state === 'emit' && getComputedStyle(node).visibility === 'visible' && rect.width > 0 && rect.height > 0
+ }, id)).toBe(true)
+}
+
+test.afterEach(async ({ page }, testInfo) => {
+ if (page.isClosed())
+ return
+ const evidence = await page.evaluate(() => {
+ if (window.maskBoundaryEvidence && window.art && !window.art.isDestroy)
+ window.art.destroy(false)
+ return window.maskBoundaryEvidence ?? null
+ })
+ await testInfo.attach('danmuku-mask-boundary-evidence', { contentType: 'application/json', body: JSON.stringify(evidence) })
+})
+
+for (const core of ['published', 'candidate']) {
+ test(`${core}: Danmuku retains the core layer and external CSS mask across commands and retained-HTML destroy`, async ({ page }, testInfo) => {
+ const external = await setup(page, core, testInfo)
+ const initial = await assertLayer(page, 'after-registration')
+ const image = initial.styles.find(item => item.name === 'mask-image')
+ expect(image.value).toContain('data:image/svg+xml,')
+ expect(image.computed).toContain('data:image/svg+xml,')
+ await renderRow(page, 'MASK-BOUNDARY-EMIT')
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0)
+ await assertLayer(page, 'after-native-emit')
+ await testInfo.attach('danmuku-mask-boundary-playing', { contentType: 'image/png', body: await page.screenshot() })
+
+ const reset = await page.evaluate(() => {
+ const owner = window.maskBoundaryPlugin.reset()
+ return { sameOwner: owner === window.maskBoundaryOwner, states: owner.queue.map(item => item.$state) }
+ })
+ expect(reset).toEqual({ sameOwner: true, states: ['wait'] })
+ await assertLayer(page, 'after-reset')
+
+ const replacement = await page.evaluate(async () => {
+ window.maskBoundaryPlugin.config({ danmuku: [{ id: 'CONFIGURED-REPLACEMENT', text: 'CONFIGURED-REPLACEMENT', time: 100 }] })
+ const owner = await window.maskBoundaryPlugin.load()
+ return { sameOwner: owner === window.maskBoundaryOwner, ids: owner.queue.map(item => item.id) }
+ })
+ expect(replacement).toEqual({ sameOwner: true, ids: ['CONFIGURED-REPLACEMENT'] })
+ await assertLayer(page, 'after-no-argument-load')
+ await renderRow(page, 'MASK-BOUNDARY-AFTER-LOAD')
+ await assertLayer(page, 'after-replacement-native-emit')
+
+ await page.evaluate(() => window.maskBoundaryPlugin.hide())
+ expect((await assertLayer(page, 'after-hide')).opacity).toBe('0')
+ await page.evaluate(() => window.maskBoundaryPlugin.show())
+ expect((await assertLayer(page, 'after-show')).opacity).toBe('1')
+
+ const beforeDestroy = await page.evaluate(() => ({ workers: window.maskBoundaryEvidence.workers, errors: window.maskBoundaryEvidence.errors }))
+ expect(beforeDestroy.errors).toEqual([])
+ expect(beforeDestroy.workers).toHaveLength(1)
+ expect(beforeDestroy.workers[0].requests.length).toBeGreaterThanOrEqual(2)
+ expect(beforeDestroy.workers[0].replies.length).toBeGreaterThanOrEqual(2)
+ await page.evaluate(() => window.art.destroy(false))
+ const destroyed = await assertLayer(page, 'after-destroy-false')
+ expect(destroyed.children).toBe(0)
+ // Use the native frame clock to detect immediate late plugin writes after cleanup.
+ await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))))
+ const settled = await assertLayer(page, 'after-destroy-native-frames')
+ expect(settled.children).toBe(0)
+ const terminal = await page.evaluate(() => ({ workers: window.maskBoundaryEvidence.workers, errors: window.maskBoundaryEvidence.errors }))
+ expect(terminal.errors).toEqual([])
+ expect(terminal.workers[0].terminated).toBe(1)
+ expect(terminal.workers[0].requests).toEqual(beforeDestroy.workers[0].requests)
+ expect(external).toEqual([])
+ })
+}
diff --git a/test/browser/danmuku-stability.spec.js b/test/browser/danmuku-stability.spec.js
new file mode 100644
index 000000000..dd45ecfcf
--- /dev/null
+++ b/test/browser/danmuku-stability.spec.js
@@ -0,0 +1,194 @@
+import assert from 'node:assert/strict'
+import fs from 'node:fs'
+import process from 'node:process'
+import { ensureArchive, hash, readMember } from '../../refactor/scripts/releases.mjs'
+import { compilePackage } from '../helpers/load.js'
+import { expect, test } from './fixtures.js'
+
+const implementations = new Map()
+test.beforeAll(async () => {
+ const release = JSON.parse(fs.readFileSync(new URL('../../refactor/baselines/danmuku-release.json', import.meta.url), 'utf8')).release
+ const member = `package/${release.manifest.main.replace(/^\.\//u, '')}`
+ const published = readMember(await ensureArchive(release), member)
+ assert.equal(hash(published), release.files[member])
+ implementations.set('published', published.toString())
+ implementations.set('candidate', process.env.ARTPLAYER_DANMUKU_ARTIFACT
+ ? fs.readFileSync(process.env.ARTPLAYER_DANMUKU_ARTIFACT, 'utf8')
+ : await compilePackage('artplayer-plugin-danmuku', 'umd'))
+})
+
+for (const implementation of ['published', 'candidate']) {
+ for (const rate of [2, 20]) {
+ test(`${implementation}: ${rate} rows per second across three native playback cycles`, async ({ page }, testInfo) => {
+ // Three 14-second media cycles plus setup/teardown; this is a bounded soak,
+ // not the ordinary short browser test deadline or a synthetic clock jump.
+ test.setTimeout(90000)
+ await page.goto('/test/player.html?core=candidate')
+ const code = implementations.get(implementation)
+ await page.addScriptTag({ content: code })
+ await page.evaluate(() => window.createPlayer('/assets/sample/video.mp4'))
+ await page.click('#play')
+ await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1)
+ await page.click('#pause')
+ await page.evaluate(() => {
+ const art = window.art
+ const evidence = window.stabilityEvidence = { workers: [], frames: [], samples: [], visible: [], recycled: [], callbacks: [], cycles: [], errors: [], allocations: 0, reuses: 0, bypassedPool: 0 }
+ const NativeWorker = window.Worker
+ window.Worker = class extends NativeWorker {
+ constructor(...args) {
+ super(...args)
+ this.record = { posts: 0, replies: 0, terminated: 0, errors: [] }
+ evidence.workers.push(this.record)
+ this.addEventListener('message', () => this.record.replies++)
+ this.addEventListener('error', event => this.record.errors.push(event.message))
+ }
+
+ postMessage(...args) {
+ this.record.posts++
+ return super.postMessage(...args)
+ }
+
+ terminate() {
+ this.record.terminated++
+ return super.terminate()
+ }
+ }
+ art.on('artplayerPluginDanmuku:error', error => evidence.errors.push(String(error)))
+ art.on('artplayerPluginDanmuku:visible', row => evidence.visible.push({ id: row.id, time: art.currentTime, wall: performance.now() }))
+ art.plugins.add(window.artplayerPluginDanmuku({
+ danmuku: [],
+ heatmap: false,
+ emitter: false,
+ speed: 1,
+ antiOverlap: false,
+ beforeVisible(row) {
+ evidence.callbacks.push({ id: row.id, time: art.currentTime })
+ return true
+ },
+ }))
+ const owner = window.stabilityOwner = art.plugins.artplayerPluginDanmuku.config({})
+ const acquire = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(owner), '$ref').get
+ const acquired = new WeakSet()
+ Object.defineProperty(owner, '$ref', { configurable: true, get() {
+ const available = new Set(this.$refs)
+ const ref = acquire.call(this)
+ if (available.size && !available.has(ref))
+ evidence.bypassedPool++
+ if (acquired.has(ref))
+ evidence.reuses++
+ else evidence.allocations++
+ acquired.add(ref)
+ return ref
+ } })
+ const getter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(owner), 'readys').get
+ Object.defineProperty(owner, 'readys', { configurable: true, get() {
+ const rows = getter.call(this)
+ evidence.samples.push({ time: art.currentTime, wall: performance.now(), ids: rows.map(row => row.id) })
+ return rows
+ } })
+ const makeWait = owner.makeWait.bind(owner)
+ owner.makeWait = (row) => {
+ if (row.$state === 'emit')
+ evidence.recycled.push({ id: row.id, time: art.currentTime })
+ return makeWait(row)
+ }
+ const frame = (wall) => {
+ if (art.playing)
+ evidence.frames.push({ wall, time: art.currentTime })
+ window.stabilityFrame = requestAnimationFrame(frame)
+ }
+ window.stabilityFrame = requestAnimationFrame(frame)
+ })
+ try {
+ for (let cycle = 0; cycle < 3; cycle++) {
+ await page.evaluate(async ({ cycle, rate }) => {
+ const art = window.art
+ const base = art.currentTime
+ const rows = Array.from({ length: 12 * rate }, (_, index) => ({ id: `${cycle}-${index}`, text: `Row ${index}`, time: base + 0.5 + index / rate, mode: index % 3 }))
+ await art.plugins.artplayerPluginDanmuku.load(rows)
+ window.stabilityEnd = base + 14
+ window.stabilityEvidence.cycles.push({ cycle, base, rows: rows.map(row => ({ id: row.id, time: row.time })), startWall: performance.now() })
+ }, { cycle, rate })
+ await page.click('#play')
+ await expect.poll(() => page.evaluate(() => window.art.currentTime >= window.stabilityEnd), { timeout: 22000 }).toBe(true)
+ await page.click('#pause')
+ const snapshot = await page.evaluate(() => {
+ const owner = window.stabilityOwner
+ const record = window.stabilityEvidence.cycles.at(-1)
+ const ids = new Set(record.rows.map(row => row.id))
+ const visible = window.stabilityEvidence.visible.filter(row => ids.has(row.id))
+ const sampled = new Set(window.stabilityEvidence.samples.flatMap(sample => sample.ids).filter(id => ids.has(id)))
+ const shown = new Set(visible.map(row => row.id))
+ const refs = owner.queue.map(row => row.$ref).filter(Boolean)
+ const queue = new Set(owner.queue)
+ const members = Object.values(owner.states).flat()
+ const memory = performance.memory
+ Object.assign(record, {
+ endWall: performance.now(),
+ time: window.art.currentTime,
+ decodedWidth: window.art.video.videoWidth,
+ visibleCount: visible.length,
+ uniqueVisible: shown.size,
+ missedSampling: record.rows.filter(row => !sampled.has(row.id)).map(row => row.id),
+ sampledNotVisible: record.rows.filter(row => sampled.has(row.id) && !shown.has(row.id)).map(row => row.id),
+ queue: owner.queue.length,
+ states: Object.fromEntries(Object.entries(owner.states).map(([state, rows]) => [state, rows.length])),
+ nodes: owner.$danmuku.children.length,
+ pooled: owner.$refs.length,
+ uniquePool: new Set(owner.$refs).size,
+ referenced: refs.length,
+ distinctReferences: new Set(refs).size,
+ uniqueStateMembers: new Set(members).size,
+ validStateMembers: Object.entries(owner.states).every(([state, rows]) => rows.every(row => queue.has(row) && row.$state === state)),
+ heap: memory ? { used: memory.usedJSHeapSize, total: memory.totalJSHeapSize } : null,
+ })
+ return record
+ })
+ expect(snapshot.decodedWidth).toBeGreaterThan(0)
+ expect(snapshot.time - snapshot.base).toBeGreaterThanOrEqual(14)
+ // load(rows) appends by public contract; old rows stay in the queue.
+ expect(snapshot.queue).toBe((cycle + 1) * 12 * rate)
+ expect(Object.values(snapshot.states).reduce((sum, count) => sum + count, 0)).toBe(snapshot.queue)
+ if (implementation === 'candidate') {
+ expect(snapshot.missedSampling).toEqual([])
+ expect(snapshot.sampledNotVisible).toEqual([])
+ expect(snapshot.visibleCount).toBe(12 * rate)
+ expect(snapshot.uniqueVisible).toBe(12 * rate)
+ expect(snapshot.referenced).toBe(0)
+ expect(snapshot.uniquePool).toBe(snapshot.pooled)
+ expect(snapshot.nodes).toBe(snapshot.pooled)
+ expect(snapshot.uniqueStateMembers).toBe(snapshot.queue)
+ expect(snapshot.validStateMembers).toBe(true)
+ }
+ }
+ }
+ finally {
+ const evidence = await page.evaluate(() => {
+ cancelAnimationFrame(window.stabilityFrame)
+ window.art.destroy()
+ return { ...window.stabilityEvidence, destroyed: window.art.isDestroy, retainedPlayerRoots: document.querySelectorAll('.art-video-player').length }
+ })
+ await testInfo.attach('danmuku-stability-observation', { contentType: 'application/json', body: JSON.stringify({ implementation, rate, sha256: hash(code), evidence, scope: 'Three bounded real media cycles; published defects are observed, candidate delivery and resource ownership are asserted. Optional unforced heap readings are not leak proof or comparable across engines.' }) })
+ expect(evidence.destroyed).toBe(true)
+ expect(evidence.retainedPlayerRoots).toBe(0)
+ expect(evidence.errors).toEqual([])
+ expect(evidence.workers).toHaveLength(1)
+ if (implementation === 'candidate' && evidence.cycles.length === 3) {
+ const expected = evidence.cycles.flatMap(cycle => cycle.rows.map(row => row.id)).sort()
+ expect(evidence.visible.map(row => row.id).sort()).toEqual(expected)
+ expect(evidence.recycled.map(row => row.id).sort()).toEqual(expected)
+ expect(evidence.bypassedPool).toBe(0)
+ expect(evidence.reuses).toBeGreaterThan(0)
+ expect(evidence.allocations + evidence.reuses).toBe(expected.length)
+ expect(evidence.cycles.at(-1).nodes).toBe(evidence.allocations)
+ }
+ for (const worker of evidence.workers) {
+ expect(worker.terminated).toBe(1)
+ expect(worker.errors).toEqual([])
+ if (implementation === 'candidate')
+ expect(worker.posts).toBe(worker.replies)
+ }
+ }
+ })
+ }
+}