@kangsicj/nexussync 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/assets/icon.svg +22 -0
- package/dist/NexusSync.meta.js +5 -6
- package/dist/NexusSync.user.js +564 -81
- package/package.json +26 -6
package/dist/NexusSync.user.js
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
// @author kangsicj
|
|
7
7
|
// @homepageURL https://github.com/kangsicj/NexusSync
|
|
8
8
|
// @supportURL https://fairy.hada.io/@jinny
|
|
9
|
+
// @icon https://cdn.jsdelivr.net/npm/@kangsicj/nexussync@latest/assets/icon.svg
|
|
9
10
|
// @updateURL https://cdn.jsdelivr.net/npm/@kangsicj/nexussync@latest/dist/NexusSync.meta.js
|
|
10
11
|
// @downloadURL https://cdn.jsdelivr.net/npm/@kangsicj/nexussync@latest/dist/NexusSync.user.js
|
|
11
|
-
// @version 1.
|
|
12
|
-
// @description Watch
|
|
13
|
-
// @description:ko
|
|
12
|
+
// @version 1.1.0
|
|
13
|
+
// @description Watch any web video together in perfect sync: cinema mode, live AI subtitles & translation, chat bubbles with auto-translation, quick ink, cover, go-together to the next episode.
|
|
14
|
+
// @description:ko 어떤 웹 영상이든 완벽한 싱크로 함께 보기: 시네마 모드, 실시간 AI 자막·번역, 자동 번역 말풍선 채팅, 잠깐 그리기, 가리기, 다음 화도 함께.
|
|
14
15
|
// @match *://*/*
|
|
15
16
|
// @include *
|
|
16
17
|
// @allFrames true
|
|
@@ -26,14 +27,12 @@
|
|
|
26
27
|
// @grant GM.xmlHttpRequest
|
|
27
28
|
// @connect translate.googleapis.com
|
|
28
29
|
// @connect nexussync-dd5b4-default-rtdb.asia-southeast1.firebasedatabase.app
|
|
29
|
-
// @connect esm.sh
|
|
30
|
-
// @connect cdn.jsdelivr.net
|
|
31
30
|
// @connect api.openai.com
|
|
32
31
|
// @connect api.groq.com
|
|
33
32
|
// @connect api.anthropic.com
|
|
34
33
|
// @connect api-free.deepl.com
|
|
35
34
|
// @connect api.deepl.com
|
|
36
|
-
// @require https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.5.0/lz-string.min.js
|
|
35
|
+
// @require https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.5.0/lz-string.min.js#sha256=95f4d1cbf099f57161b664bc048426ec3df92637801a4c79116e83315aa787e7
|
|
37
36
|
// ==/UserScript==
|
|
38
37
|
|
|
39
38
|
(async function () {
|
|
@@ -41,12 +40,15 @@
|
|
|
41
40
|
|
|
42
41
|
// The version of the code that is actually running (the manager's metadata can lag
|
|
43
42
|
// behind when an old copy is still installed).
|
|
44
|
-
const NXU_VERSION = '1.
|
|
43
|
+
const NXU_VERSION = '1.1.0';
|
|
45
44
|
// Rank used by the one-instance guard below and to tell newer builds apart in a room.
|
|
46
45
|
// It is independent of the public version (1.0.0 is the first public release, after
|
|
47
46
|
// private builds that reached ranks up to 10.2.0), so every older copy still installed
|
|
48
47
|
// steps aside instead of this release.
|
|
49
|
-
const NXU_RANK = '11.
|
|
48
|
+
const NXU_RANK = '11.1.0';
|
|
49
|
+
const NXU_SESSION = Math.random().toString(36).slice(2, 10); // this page load // raise with every release
|
|
50
|
+
// App icon (same artwork as assets/icon.svg / @icon), inlined so it shows offline too.
|
|
51
|
+
const NXU_ICON = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTYgMjU2IiByb2xlPSJpbWciIGFyaWEtbGFiZWw9Ik5leHVzU3luYyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJueGJnIiB4MT0iMCIgeTE9IjAiIHgyPSIxIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjNWIyZWZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmY0ZmEzIi8+PC9saW5lYXJHcmFkaWVudD48cmFkaWFsR3JhZGllbnQgaWQ9Im54Z2xvdyIgY3g9IjAuODIiIGN5PSIwLjE0IiByPSIwLjciPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzdjZjlmZiIgc3RvcC1vcGFjaXR5PSIwLjU1Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjN2NmOWZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L3JhZGlhbEdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0ibnhwbGF5IiB4MT0iMCIgeTE9IjAiIHgyPSIxIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZlM2YxIi8+PC9saW5lYXJHcmFkaWVudD48Y2xpcFBhdGggaWQ9Im54ciI+PHJlY3Qgd2lkdGg9IjI1NiIgaGVpZ2h0PSIyNTYiIHJ4PSI1OCIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNueHIpIj48cmVjdCB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgZmlsbD0idXJsKCNueGJnKSIvPjxyZWN0IHdpZHRoPSIyNTYiIGhlaWdodD0iMjU2IiBmaWxsPSJ1cmwoI254Z2xvdykiLz48ZyBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMTUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PHBhdGggZD0iTTYwIDExNiBBNzAgNzAgMCAwIDEgMTc4IDcyIi8+PHBhdGggZD0iTTE5NiAxNDAgQTcwIDcwIDAgMCAxIDc4IDE4NCIvPjwvZz48cGF0aCBkPSJNMTg2IDUwIEwyMDAgOTIgTDE1NyA4NiBaIiBmaWxsPSIjZmZmZmZmIi8+PHBhdGggZD0iTTcwIDIwNiBMNTYgMTY0IEw5OSAxNzAgWiIgZmlsbD0iI2ZmZmZmZiIvPjxwYXRoIGQ9Ik0xMTAgOTIgUTEwNCA4OCAxMDQgOTYgTDEwNCAxNjAgUTEwNCAxNjggMTEwIDE2NCBMMTYyIDEzMiBRMTY4IDEyOCAxNjIgMTI0IFoiIGZpbGw9InVybCgjbnhwbGF5KSIvPjwvZz48L3N2Zz4=';
|
|
50
52
|
const IS_TOP = (() => { try { return window === window.top; } catch (_) { return false; } })();
|
|
51
53
|
const IS_IOS = /iPad|iPhone|iPod/.test(navigator.userAgent) || (navigator.platform === 'MacIntel' && Number(navigator.maxTouchPoints) > 1);
|
|
52
54
|
const IS_TOUCH = IS_IOS || (typeof matchMedia === 'function' && matchMedia('(pointer: coarse)').matches);
|
|
@@ -169,7 +171,7 @@
|
|
|
169
171
|
'nxu_idle_timeout', 'nxu_sub_size', 'nxu_sub_opacity', 'nxu_sub_position', 'nxu_speaker_language',
|
|
170
172
|
'nxu_subtitle_language', 'nxu_audio_mode', 'nxu_translation_provider', 'nxu_stt_local_first',
|
|
171
173
|
'nxu_smart_speech_locale', 'nxu_fab_pos', 'nxu_asr_provider', 'nxu_key_openai', 'nxu_key_anthropic', 'nxu_key_groq', 'nxu_key_deepl',
|
|
172
|
-
'nxu_model_openai', 'nxu_model_anthropic', 'nxu_cinema_ambient', 'nxu_cinema_fit', 'nxu_cc_remaining', 'nxu_cinema_controls', 'nxu_nickname', 'nxu_color', 'nxu_quick_replies', 'nxu_chat_translate', 'nxu_sync_offset', 'nxu_cover_band', 'nxu_cover_marks', 'nxu_travel', 'nxu_glossary', 'nxu_panel_size_chat-panel', 'nxu_panel_size_sub-log-panel', 'nxu_panel_size_debug-panel', 'nxu_panel_size_trans-modal', 'nxu_cinema_rotate', 'nxu_rotate_denied_' + HOST
|
|
174
|
+
'nxu_model_openai', 'nxu_model_anthropic', 'nxu_cinema_ambient', 'nxu_cinema_fit', 'nxu_cc_remaining', 'nxu_cinema_controls', 'nxu_nickname', 'nxu_color', 'nxu_quick_replies', 'nxu_chat_translate', 'nxu_sync_offset', 'nxu_cover_band', 'nxu_cover_marks', 'nxu_travel', 'nxu_auto_next', 'nxu_auto_cinema_sites', 'nxu_glossary', 'nxu_panel_size_chat-panel', 'nxu_panel_size_sub-log-panel', 'nxu_panel_size_debug-panel', 'nxu_panel_size_trans-modal', 'nxu_cinema_rotate', 'nxu_rotate_denied_' + HOST
|
|
173
175
|
]);
|
|
174
176
|
|
|
175
177
|
// ───────────────────────── Cross-origin HTTP (GM xhr first, fetch fallback)
|
|
@@ -238,7 +240,7 @@
|
|
|
238
240
|
hardSyncTolerance: 2.5,
|
|
239
241
|
softSyncTolerance: 0.25,
|
|
240
242
|
syncHeartbeatMs: 3000,
|
|
241
|
-
emojis: ['
|
|
243
|
+
emojis: ['😂', '😭', '😡', '💦', '🍪', '☕', '😘', '🖕'],
|
|
242
244
|
chunkSize: 2000,
|
|
243
245
|
relayBatchInterval: 250,
|
|
244
246
|
relayBatchIntervalTight: 80,
|
|
@@ -380,7 +382,8 @@
|
|
|
380
382
|
videoHookController: null,
|
|
381
383
|
hostHeartbeatTimer: null,
|
|
382
384
|
_presenceTimer: null,
|
|
383
|
-
|
|
385
|
+
// Rises across page loads too (a reloaded page keeps its identity when it rejoins).
|
|
386
|
+
_videoSequence: Date.now() - 1700000000000,
|
|
384
387
|
_lastVideoSeqBySource: new Map(),
|
|
385
388
|
_processedVideoEvents: new Map(),
|
|
386
389
|
_acceptedVideoState: null,
|
|
@@ -619,8 +622,8 @@
|
|
|
619
622
|
travelBack: 'Back in the room', travelMoved: 'Moved to “{title}” · tap to go together', travelGoing: 'Going together…',
|
|
620
623
|
chatTrOn: 'Auto-translate: on', chatTrOff: 'Auto-translate: off', chatTrShowOrig: 'Tap to see the original', chatTrShowTr: 'Tap to see the translation', chatTrFrom: 'Translated from {lang}',
|
|
621
624
|
inkClosing: 'Closing soon — move or tap to keep drawing',
|
|
622
|
-
talkMenu: 'Chat', inkMenu: 'Quick sketch', quickEdit: 'Edit quick replies', quickEditHint: 'Separate with |', quickReset: 'Back to the default replies', save: 'Save',
|
|
623
|
-
talkTitle: 'Chat bubble', talkPlaceholder: 'Say something…', talkReplyTo: '↩ Reply to {name}', talkClose: 'Close', talkSend: 'Send', talkFull: 'Open the
|
|
625
|
+
modeSitePlayer: 'Site player in use', modeNexusPlayer: 'NexusSync player in use', modeSiteHint: 'Change subtitles or the server in the site’s player, then switch.', modeSiteHintAuto: 'Cinema started by itself. Pick subtitles or a server in the site’s player first if needed, then switch.', modeNexusHint: 'Everything is controlled by NexusSync. The site’s own settings are one tap away.', modeUseNexus: 'Use NexusSync player', modeUseSite: 'Use site player', autoCinemaStopSite: 'No auto-cinema on this site', autoCinemaOnSite: 'Auto-cinema on for {site}', autoCinemaOffSite: 'Auto-cinema off for {site}', autoCinemaBtnOn: 'Auto-cinema: on (this site)', autoCinemaBtnOff: 'Auto-cinema: off (this site)', ccPip: 'Picture-in-Picture (keep watching in a small window)', nextEpTitle: 'Up next', nextEpGo: 'Next episode', nextEpCancel: 'Stay on this episode', nextEpGoing: 'Next episode…', talkMenu: 'Chat', inkMenu: 'Quick sketch', quickEdit: 'Edit quick replies', quickEditHint: 'Separate with |', quickReset: 'Back to the default replies', save: 'Save',
|
|
626
|
+
talkTitle: 'Chat bubble', talkPlaceholder: 'Say something…', talkReplyTo: '↩ Reply to {name}', talkClose: 'Close', talkSend: 'Send', talkFull: 'Open the chat history (every message so far)', talkHistory: 'History',
|
|
624
627
|
inkTitle: 'Quick sketch (fades away)', inkHint: 'Draw on the screen — it fades in a few seconds', inkDone: 'Done', inkBubble: 'is sketching on the screen — tap to draw back',
|
|
625
628
|
you: 'You', roomBuffering: '⏳ {name} is loading… everyone waits', roomResume: '▶️ Everyone is ready — playing together', roomRate: '⏩ Speed {rate}x synced',
|
|
626
629
|
youBuffering: '⏳ Your video is loading — the room waits for you', shieldResumeTitle: 'Tap to rejoin playback', shieldResumeText: 'The browser paused this video. Tap once to continue in sync with the room.',
|
|
@@ -702,8 +705,8 @@
|
|
|
702
705
|
travelBack: '방에 다시 연결했어요', travelMoved: '「{title}」(으)로 이동했어요 · 눌러서 같이 가기', travelGoing: '같이 이동하는 중…',
|
|
703
706
|
chatTrOn: '자동 번역 켜짐', chatTrOff: '자동 번역 꺼짐', chatTrShowOrig: '눌러서 원문 보기', chatTrShowTr: '눌러서 번역 보기', chatTrFrom: '{lang}에서 번역됨',
|
|
704
707
|
inkClosing: '곧 닫혀요 — 계속 그리려면 움직이거나 눌러 주세요',
|
|
705
|
-
talkMenu: '말풍선 채팅', inkMenu: '잠깐 그리기', quickEdit: '빠른 답장 편집', quickEditHint: '| 로 구분', quickReset: '기본 답장으로', save: '저장',
|
|
706
|
-
talkTitle: '말풍선 채팅', talkPlaceholder: '메시지 보내기…', talkReplyTo: '↩ {name} 님에게 답장', talkClose: '닫기', talkSend: '보내기', talkFull: '전체
|
|
708
|
+
modeSitePlayer: '사이트 플레이어 사용 중', modeNexusPlayer: 'NexusSync 플레이어 사용 중', modeSiteHint: '자막이나 서버는 사이트 플레이어에서 바꾼 뒤 전환하세요.', modeSiteHintAuto: '시네마 모드가 자동으로 켜졌어요. 필요하면 사이트 플레이어에서 자막·서버를 먼저 고른 뒤 전환하세요.', modeNexusHint: 'NexusSync가 모든 조작을 맡아요. 사이트 설정은 한 번 탭으로 돌아갈 수 있어요.', modeUseNexus: 'NexusSync 플레이어로', modeUseSite: '사이트 플레이어로', autoCinemaStopSite: '이 사이트는 자동 시네마 끄기', autoCinemaOnSite: '{site}에서 자동 시네마 켜짐', autoCinemaOffSite: '{site}에서 자동 시네마 꺼짐', autoCinemaBtnOn: '자동 시네마: 켬 (이 사이트)', autoCinemaBtnOff: '자동 시네마: 끔 (이 사이트)', ccPip: 'PiP (작은 창으로 계속 보기)', nextEpTitle: '다음 화', nextEpGo: '다음 화 보기', nextEpCancel: '이번 화에 머물기', nextEpGoing: '다음 화로 이동하는 중…', talkMenu: '말풍선 채팅', inkMenu: '잠깐 그리기', quickEdit: '빠른 답장 편집', quickEditHint: '| 로 구분', quickReset: '기본 답장으로', save: '저장',
|
|
709
|
+
talkTitle: '말풍선 채팅', talkPlaceholder: '메시지 보내기…', talkReplyTo: '↩ {name} 님에게 답장', talkClose: '닫기', talkSend: '보내기', talkFull: '지금까지의 대화 기록 전체 보기', talkHistory: '대화 기록',
|
|
707
710
|
inkTitle: '잠깐 그리기 (몇 초 뒤 사라짐)', inkHint: '화면에 그려 보세요 — 몇 초 뒤 사라져요', inkDone: '완료', inkBubble: '님이 화면에 그리고 있어요 — 탭해서 같이 그리기',
|
|
708
711
|
you: '나', roomBuffering: '⏳ {name} 기기 로딩 중… 모두 잠시 대기', roomResume: '▶️ 모두 준비됨 — 함께 재생합니다', roomRate: '⏩ {rate}배속 동기화',
|
|
709
712
|
youBuffering: '⏳ 이 기기 영상 로딩 중 — 방이 기다려 줍니다', shieldResumeTitle: '탭해서 다시 재생', shieldResumeText: '브라우저가 이 영상을 멈췄습니다. 한 번 탭하면 방과 맞춰 이어서 재생합니다.',
|
|
@@ -1196,7 +1199,7 @@
|
|
|
1196
1199
|
return v === 'cover' || v === 'fill' ? v : 'contain';
|
|
1197
1200
|
},
|
|
1198
1201
|
// Cinema controls mode: the site's own player UI is hidden so only one set shows.
|
|
1199
|
-
nexusControls() { return IS_TOP ?
|
|
1202
|
+
nexusControls() { return IS_TOP ? cinemaControlsMode() !== 'site' : this._frameNexus === true; },
|
|
1200
1203
|
_startAmbient(video, root) {
|
|
1201
1204
|
this._stopAmbient();
|
|
1202
1205
|
if (!video || !root || !this.ambientEnabled()) return;
|
|
@@ -1377,8 +1380,12 @@
|
|
|
1377
1380
|
else this._frameFit = fit;
|
|
1378
1381
|
this._restyle();
|
|
1379
1382
|
},
|
|
1380
|
-
setControls(mode) {
|
|
1381
|
-
|
|
1383
|
+
setControls(mode, { save = true } = {}) {
|
|
1384
|
+
// save:false (automatic cinema) uses the site's player for this visit only.
|
|
1385
|
+
if (IS_TOP) {
|
|
1386
|
+
if (save) { STATE.controlsOverride = null; STORE.set('nxu_cinema_controls', mode === 'site' ? 'site' : 'nexus'); }
|
|
1387
|
+
else STATE.controlsOverride = mode === 'site' ? 'site' : 'nexus';
|
|
1388
|
+
}
|
|
1382
1389
|
this._restyle();
|
|
1383
1390
|
},
|
|
1384
1391
|
|
|
@@ -1487,6 +1494,8 @@
|
|
|
1487
1494
|
try { (document.exitFullscreen || document.webkitExitFullscreen)?.call(document)?.catch?.(() => { }); } catch (_) { }
|
|
1488
1495
|
}
|
|
1489
1496
|
if (!on) this._ownFullscreen = false;
|
|
1497
|
+
if (!on) { STATE.controlsOverride = null; AUTO_CINEMA.onExit(); }
|
|
1498
|
+
if (on) AUTO_CINEMA.onEnter();
|
|
1490
1499
|
if (!on && ROTATE.deg) ROTATE._tick(); // leaving cinema also leaves landscape view at once
|
|
1491
1500
|
CINEMA_UI.sync();
|
|
1492
1501
|
updateMediaButtons();
|
|
@@ -1834,7 +1843,9 @@
|
|
|
1834
1843
|
},
|
|
1835
1844
|
_decide(side) {
|
|
1836
1845
|
if (side) this._lastSide = side;
|
|
1837
|
-
|
|
1846
|
+
// Turned on with ↻: stays in landscape, but follows the phone to the other side
|
|
1847
|
+
// (left or right edge down) instead of staying stuck on the first one.
|
|
1848
|
+
if (this.manual) { if (side && this.deg && side !== this.deg) this._apply(side); return; }
|
|
1838
1849
|
if (!side) {
|
|
1839
1850
|
this.suppress = false;
|
|
1840
1851
|
if (this.deg) this._leave();
|
|
@@ -3636,7 +3647,9 @@
|
|
|
3636
3647
|
} else if (msg.t === 'pong') {
|
|
3637
3648
|
const t3 = Date.now();
|
|
3638
3649
|
const rtt = t3 - msg.t1;
|
|
3639
|
-
|
|
3650
|
+
// Everyone shares the server clock; the direct link only stands in until
|
|
3651
|
+
// this device has its own server measurement.
|
|
3652
|
+
if (!STATE._serverClockAt) STATE.clockOffset = msg.t2 - (msg.t1 + rtt / 2);
|
|
3640
3653
|
STATE.rttMs = rtt;
|
|
3641
3654
|
updateRttHUD(rtt);
|
|
3642
3655
|
logDebug(`P2P Clock Offset: ${STATE.clockOffset.toFixed(2)}ms`, "success");
|
|
@@ -4371,15 +4384,11 @@
|
|
|
4371
4384
|
window.addEventListener('pagehide', (e) => { if (!e.persisted) { try { TRAVEL.onLeavePage(); } catch (_) { } _cleanupHostNodes(); } });
|
|
4372
4385
|
|
|
4373
4386
|
async function initYjsSystem() {
|
|
4374
|
-
const sources = ['https://esm.sh/yjs@13.6.14?bundle', 'https://cdn.jsdelivr.net/npm/yjs@13.6.14/+esm'];
|
|
4375
4387
|
try {
|
|
4376
4388
|
if (ydoc) { ydoc.destroy(); ydoc = yVideo = yChat = yStrokes = yBookmarks = yPresence = null; }
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
}
|
|
4381
|
-
if (!Y) throw new Error('all sources blocked');
|
|
4382
|
-
}
|
|
4389
|
+
// The sync engine ships inside the script: no code is downloaded and run at
|
|
4390
|
+
// connect time, and sites with strict security policies work the same.
|
|
4391
|
+
if (!Y) Y = nxuLoadYjs();
|
|
4383
4392
|
ydoc = new Y.Doc();
|
|
4384
4393
|
yVideo = ydoc.getMap('video');
|
|
4385
4394
|
yChat = ydoc.getArray('chat');
|
|
@@ -4761,7 +4770,7 @@
|
|
|
4761
4770
|
syncServerClock();
|
|
4762
4771
|
try { TRAVEL.onConnected(); } catch (_) { }
|
|
4763
4772
|
// Pre-encrypted goodbye for tab close (pagehide cannot wait for encryption).
|
|
4764
|
-
encryptData({ id: 'bye_' + STATE.userId + '_' + Date.now().toString(36), t: 'peer_leave', s: STATE.senderId, d: { uid: STATE.userId } }).then(packet => { NETWORK.byePacket = packet; }).catch(() => { });
|
|
4773
|
+
encryptData({ id: 'bye_' + STATE.userId + '_' + Date.now().toString(36), t: 'peer_leave', s: STATE.senderId, d: { uid: STATE.userId, sess: NXU_SESSION } }).then(packet => { NETWORK.byePacket = packet; }).catch(() => { });
|
|
4765
4774
|
spawnMandatoryShield();
|
|
4766
4775
|
}
|
|
4767
4776
|
|
|
@@ -4773,6 +4782,10 @@
|
|
|
4773
4782
|
case 'peer_leave': {
|
|
4774
4783
|
// Everyone is equal: someone leaving never ends the room for the others.
|
|
4775
4784
|
const uid = typeof d.uid === 'string' ? d.uid : null;
|
|
4785
|
+
// The page someone just left (next episode) says goodbye while their new page
|
|
4786
|
+
// is already back in the room under the same name: that goodbye is old news.
|
|
4787
|
+
const cur = uid && yPresence ? yPresence.get(uid) : null;
|
|
4788
|
+
if (uid && typeof d.sess === 'string' && cur && typeof cur.sess === 'string' && cur.sess !== d.sess) break;
|
|
4776
4789
|
if (uid && uid !== STATE.userId) {
|
|
4777
4790
|
const name = participantName(uid);
|
|
4778
4791
|
PRESENCE.seen.delete(uid);
|
|
@@ -4894,6 +4907,11 @@
|
|
|
4894
4907
|
yVideo.observe((event, transaction) => {
|
|
4895
4908
|
if (transaction.origin === 'local' || transaction.origin === 'local-repair') return;
|
|
4896
4909
|
const observedState = _readObservedVideoState(event);
|
|
4910
|
+
// Whoever sends room updates is clearly here: two devices that each missed the
|
|
4911
|
+
// other's presence note both thought they led and kept correcting each other.
|
|
4912
|
+
if (observedState?.sourceDeviceId && observedState.sourceDeviceId !== STATE.userId && yPresence?.has(observedState.sourceDeviceId)) {
|
|
4913
|
+
PRESENCE.seen.set(observedState.sourceDeviceId, Date.now());
|
|
4914
|
+
}
|
|
4897
4915
|
if (observedState && observedState.sourceDeviceId !== STATE.userId && Date.now() < STATE.localIntentUntil) {
|
|
4898
4916
|
// Someone else acted while our own action is still on its way. This used to be
|
|
4899
4917
|
// dropped for good — so two people pressing within a second kept different
|
|
@@ -5054,7 +5072,11 @@
|
|
|
5054
5072
|
const elapsed = Math.max(-wait / 1000, 0) * base;
|
|
5055
5073
|
const expected = Math.min(time + elapsed, video.duration || Infinity);
|
|
5056
5074
|
const drift = expected - video.currentTime;
|
|
5057
|
-
|
|
5075
|
+
// Heartbeat-driven jumps are spaced out: a device that stalls right after each jump
|
|
5076
|
+
// (slow network, heavy stream) would otherwise be yanked back again and again.
|
|
5077
|
+
const hbJumpOk = action !== 'heartbeat' || Date.now() - (STATE._hbSeekAt || 0) > 8000 || Math.abs(drift) > 15;
|
|
5078
|
+
if ((Math.abs(drift) > CONFIG.hardSyncTolerance && hbJumpOk) || (action !== 'heartbeat' && Math.abs(drift) > 0.6)) {
|
|
5079
|
+
if (action === 'heartbeat') STATE._hbSeekAt = Date.now();
|
|
5058
5080
|
remoteSeek(video, expected);
|
|
5059
5081
|
RATE.apply(video, base);
|
|
5060
5082
|
STATE.syncMode = 'TIGHT';
|
|
@@ -5124,6 +5146,7 @@
|
|
|
5124
5146
|
if (idle || isSyncLeader()) {
|
|
5125
5147
|
this.drift = idle ? null : 0;
|
|
5126
5148
|
this._ema = 0;
|
|
5149
|
+
if (this._steps) { this._steps = 0; if (!idle) RATE.apply(v, room ? room.rate : RATE.base(v)); }
|
|
5127
5150
|
return;
|
|
5128
5151
|
}
|
|
5129
5152
|
const expected = Math.min(room.time + (getSyncedTime() - room.timestamp) / 1000 * room.rate + this.offset(), (v.duration || Infinity) - 0.1);
|
|
@@ -5137,15 +5160,29 @@
|
|
|
5137
5160
|
STATE._lastRemoteApplyAt = Date.now();
|
|
5138
5161
|
remoteSeek(v, expected + 0.05);
|
|
5139
5162
|
RATE.apply(v, base);
|
|
5163
|
+
this._steps = 0;
|
|
5140
5164
|
}
|
|
5141
5165
|
return;
|
|
5142
5166
|
}
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5167
|
+
// Speed nudges come in a few fixed steps and are held for a while: changing the
|
|
5168
|
+
// speed every few hundred milliseconds made some players (Safari above all) hitch
|
|
5169
|
+
// and stutter, which looked like a play/pause loop.
|
|
5170
|
+
const step = IS_IOS ? 0.03 : 0.02;
|
|
5171
|
+
const maxSteps = IS_IOS ? 1 : 2;
|
|
5172
|
+
const holdMs = IS_IOS ? 3000 : 1500;
|
|
5173
|
+
const now = Date.now();
|
|
5174
|
+
let want = 0;
|
|
5175
|
+
if (Math.abs(this._ema) > this.TOLERANCE) want = Math.sign(this._ema) * Math.min(maxSteps, Math.max(1, Math.round(Math.abs(this._ema) / 0.12)));
|
|
5176
|
+
else if (this._steps && Math.abs(this._ema) > this.TOLERANCE / 2 && Math.sign(this._ema) === Math.sign(this._steps)) want = this._steps; // hysteresis
|
|
5177
|
+
if (want === this._steps) {
|
|
5178
|
+
if (want) RATE.apply(v, base, 1 + want * step, holdMs + 1000); // keep it going
|
|
5179
|
+
return;
|
|
5148
5180
|
}
|
|
5181
|
+
if (now - (this._stepAt || 0) < holdMs && want !== 0) return;
|
|
5182
|
+
this._steps = want;
|
|
5183
|
+
this._stepAt = now;
|
|
5184
|
+
if (want) RATE.apply(v, base, 1 + want * step, holdMs + 1000);
|
|
5185
|
+
else RATE.apply(v, base);
|
|
5149
5186
|
}
|
|
5150
5187
|
};
|
|
5151
5188
|
|
|
@@ -5395,7 +5432,8 @@
|
|
|
5395
5432
|
} catch (_) { }
|
|
5396
5433
|
}
|
|
5397
5434
|
fbRequest('DELETE', path).catch(() => { });
|
|
5398
|
-
if (best
|
|
5435
|
+
if (best) {
|
|
5436
|
+
STATE._serverClockAt = Date.now();
|
|
5399
5437
|
STATE.clockOffset = best.offset;
|
|
5400
5438
|
STATE.rttMs = best.rtt;
|
|
5401
5439
|
logDebug(`Clock synced to server (offset ${Math.round(best.offset)}ms, rtt ${best.rtt}ms).`, 'success');
|
|
@@ -5425,19 +5463,28 @@
|
|
|
5425
5463
|
if (!STATE.handshakeVerified || STATE.isViewer || STATE.isReadOnly) return false;
|
|
5426
5464
|
const ids = PRESENCE.ids().filter(id => id === STATE.userId || !STATE.presenceMap[id]?.viewer);
|
|
5427
5465
|
if (!ids.includes(STATE.userId)) ids.push(STATE.userId);
|
|
5428
|
-
|
|
5429
|
-
|
|
5466
|
+
// A device in the background (hidden tab, screen off) has throttled timers and often a
|
|
5467
|
+
// paused video: it does not lead while someone is actually watching.
|
|
5468
|
+
const awake = ids.filter(id => id === STATE.userId ? !document.hidden : !STATE.presenceMap[id]?.hid);
|
|
5469
|
+
const pool = awake.length ? awake : ids;
|
|
5470
|
+
pool.sort();
|
|
5471
|
+
return pool[0] === STATE.userId;
|
|
5430
5472
|
}
|
|
5431
5473
|
|
|
5432
5474
|
function startPresence() {
|
|
5433
5475
|
if (STATE._presenceTimer) return;
|
|
5434
5476
|
const beat = () => {
|
|
5435
5477
|
if (ydoc && yPresence && STATE.role !== 'IDLE' && !STATE.isReadOnly) {
|
|
5436
|
-
ydoc.transact(() => yPresence.set(STATE.userId, { ts: Date.now(), color: STATE.color, viewer: !!STATE.isViewer, nick: STATE.nickname || '', v: NXU_VERSION, r: NXU_RANK }), 'local');
|
|
5478
|
+
ydoc.transact(() => yPresence.set(STATE.userId, { ts: Date.now(), color: STATE.color, viewer: !!STATE.isViewer, nick: STATE.nickname || '', v: NXU_VERSION, r: NXU_RANK, sess: NXU_SESSION, hid: !!document.hidden }), 'local');
|
|
5437
5479
|
}
|
|
5438
5480
|
PRESENCE.refresh();
|
|
5439
5481
|
};
|
|
5440
5482
|
beat();
|
|
5483
|
+
// Once more after the room's history has arrived: a fresh page (reload, next episode)
|
|
5484
|
+
// starts from an empty document, so its first note can lose to the one its previous
|
|
5485
|
+
// page left; a note written after the sync always wins.
|
|
5486
|
+
setTimeout(beat, 1500);
|
|
5487
|
+
setTimeout(beat, 4000);
|
|
5441
5488
|
STATE._presenceTimer = setInterval(beat, 8000);
|
|
5442
5489
|
}
|
|
5443
5490
|
|
|
@@ -5449,7 +5496,7 @@
|
|
|
5449
5496
|
// Leaving only takes *this* device out; the room goes on for everyone else.
|
|
5450
5497
|
const alone = PRESENCE.others().length === 0;
|
|
5451
5498
|
try { if (ydoc && yPresence) ydoc.transact(() => yPresence.delete(STATE.userId), 'local'); } catch (_) { }
|
|
5452
|
-
const bye = Promise.resolve(sendFirebaseCmd('peer_leave', { uid: STATE.userId }, 'nexus_rooms')).catch(() => { });
|
|
5499
|
+
const bye = Promise.resolve(sendFirebaseCmd('peer_leave', { uid: STATE.userId, sess: NXU_SESSION }, 'nexus_rooms')).catch(() => { });
|
|
5453
5500
|
if (STATE.lobbyTimer) clearTimeout(STATE.lobbyTimer);
|
|
5454
5501
|
if (STATE.role === 'HOST') wipeDatabaseCompletely('nexus_lobbies', STATE.lobbyId);
|
|
5455
5502
|
(STATE.inviteLobbies || []).forEach(id => wipeDatabaseCompletely('nexus_lobbies', id));
|
|
@@ -5466,6 +5513,7 @@
|
|
|
5466
5513
|
processedMsgIds.clear();
|
|
5467
5514
|
RTC.destroy();
|
|
5468
5515
|
STATE.clockOffset = 0;
|
|
5516
|
+
STATE._serverClockAt = 0;
|
|
5469
5517
|
STATE.rttMs = null;
|
|
5470
5518
|
releaseVideoHooks(STATE.video);
|
|
5471
5519
|
MEDIA_SESSION.release();
|
|
@@ -5593,6 +5641,11 @@
|
|
|
5593
5641
|
}
|
|
5594
5642
|
|
|
5595
5643
|
// ───────────────────────── Media helpers shared by chat, bookmarks and PiP
|
|
5644
|
+
function cinemaControlsMode() {
|
|
5645
|
+
if (STATE.controlsOverride) return STATE.controlsOverride;
|
|
5646
|
+
return STORE.get('nxu_cinema_controls', 'nexus') === 'site' ? 'site' : 'nexus';
|
|
5647
|
+
}
|
|
5648
|
+
|
|
5596
5649
|
function currentMediaInfo() {
|
|
5597
5650
|
if (STATE.video) {
|
|
5598
5651
|
return { kind: 'video', el: STATE.video, time: STATE.video.currentTime, duration: STATE.video.duration, paused: STATE.video.paused };
|
|
@@ -6077,7 +6130,9 @@
|
|
|
6077
6130
|
|
|
6078
6131
|
function updateSmartPosition(wrapper, fab, dock, reactPill) {
|
|
6079
6132
|
if (!wrapper || !fab || !dock || !reactPill) return;
|
|
6080
|
-
|
|
6133
|
+
// In the container's own frame: screen rectangles are turned 90° in landscape view on
|
|
6134
|
+
// iPhone, which put the menu off screen.
|
|
6135
|
+
const rect = localBox(wrapper), w = getW(), h = getH();
|
|
6081
6136
|
const isLeft = rect.left + 24 < w / 2, isTop = rect.top + 24 < h / 2;
|
|
6082
6137
|
[dock, reactPill].forEach(el => { el.style.left = el.style.right = el.style.top = el.style.bottom = 'auto'; });
|
|
6083
6138
|
fab.style.top = '0px'; fab.style.left = '0px';
|
|
@@ -6118,7 +6173,13 @@
|
|
|
6118
6173
|
let probe = container.querySelector('.safe-probe');
|
|
6119
6174
|
if (!probe) { probe = createEl('div', 'safe-probe'); container.appendChild(probe); }
|
|
6120
6175
|
const cs = getComputedStyle(probe);
|
|
6121
|
-
|
|
6176
|
+
const env = { top: parseFloat(cs.paddingTop) || 0, right: parseFloat(cs.paddingRight) || 0, bottom: parseFloat(cs.paddingBottom) || 0, left: parseFloat(cs.paddingLeft) || 0 };
|
|
6177
|
+
// Landscape view on iPhone turns the UI, but the notch and home bar stay where they
|
|
6178
|
+
// are on the screen: map them into the UI's own frame.
|
|
6179
|
+
const deg = typeof ROTATE !== 'undefined' ? ROTATE.deg : 0;
|
|
6180
|
+
if (deg === 90) return { top: env.right, right: env.bottom, bottom: env.left, left: env.top };
|
|
6181
|
+
if (deg === -90) return { top: env.left, right: env.top, bottom: env.right, left: env.bottom };
|
|
6182
|
+
return env;
|
|
6122
6183
|
}
|
|
6123
6184
|
|
|
6124
6185
|
// Position of an element inside the NexusSync container, in the container's own frame.
|
|
@@ -6374,7 +6435,7 @@
|
|
|
6374
6435
|
// ───────────────────────── UI stylesheet
|
|
6375
6436
|
const UI_CSS = `
|
|
6376
6437
|
:host { all: initial; }
|
|
6377
|
-
.nexus-container { --txt:#fff; --glass:rgba(20,25,30,0.
|
|
6438
|
+
.nexus-container { --txt:#fff; --glass:rgba(20,25,30,0.34); --glass-strong:rgba(18,22,28,0.5); --accent:#00e676; --glass-active:rgba(0,230,118,0.28);
|
|
6378
6439
|
--sub-size:20px; --sub-original-size:13px; --sub-interim-size:17px; --sub-opacity:0.9; --sub-bg:rgba(8,10,14,0.82);
|
|
6379
6440
|
font-family: system-ui, -apple-system, "Segoe UI", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif; font-size:13px; color:var(--txt);
|
|
6380
6441
|
container-type:size; container-name:nexus; width:100%; height:100%; position:absolute; inset:0; pointer-events:none; }
|
|
@@ -6401,7 +6462,7 @@
|
|
|
6401
6462
|
pushes past the menu edge (that briefly made a scrollbar appear). */
|
|
6402
6463
|
.dock .notify-pulse, .nexus-panel .notify-pulse { animation-name:pulseGlow; }
|
|
6403
6464
|
@keyframes pulseGlow { 0%,100% { box-shadow:0 0 6px rgba(0,230,118,0.35); filter:brightness(1); } 50% { box-shadow:0 0 16px rgba(0,230,118,0.85), inset 0 0 10px rgba(0,230,118,0.25); filter:brightness(1.18); } }
|
|
6404
|
-
#reaction-pill { position:absolute; background:var(--glass); backdrop-filter:blur(
|
|
6465
|
+
#reaction-pill { position:absolute; background:var(--glass); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); border:1px solid rgba(255,255,255,0.2); border-radius:24px; padding:0 4px; display:flex; align-items:center;
|
|
6405
6466
|
opacity:0; pointer-events:none; transition:opacity 0.3s, transform 0.3s; white-space:nowrap; z-index:95; height:48px; }
|
|
6406
6467
|
#reaction-pill.visible { opacity:1; pointer-events:auto; }
|
|
6407
6468
|
#reaction-pill { max-width:calc(100vw - 72px); max-width:calc(100cqw - 72px); overflow-x:auto; overflow-y:hidden; scrollbar-width:none; }
|
|
@@ -6420,7 +6481,7 @@
|
|
|
6420
6481
|
@media (prefers-reduced-motion: reduce) { .react-btn.pop, .react-btn.pop::after, .nx-spark { animation:none !important; } }
|
|
6421
6482
|
.presence-pill { position:absolute; font-size:11px; padding:3px 8px; border-radius:99px; background:rgba(0,0,0,0.6); color:#e0e0e0; white-space:nowrap; pointer-events:auto; }
|
|
6422
6483
|
.dock { position:absolute; background:var(--glass-strong); border-radius:16px; padding:10px; display:flex; flex-direction:column; gap:6px; pointer-events:none; opacity:0; border:1px solid rgba(255,255,255,0.1);
|
|
6423
|
-
transition:opacity 0.25s ease, transform 0.25s ease; box-shadow:0 10px 30px rgba(0,0,0,0.
|
|
6484
|
+
transition:opacity 0.25s ease, transform 0.25s ease; box-shadow:0 10px 30px rgba(0,0,0,0.35); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); z-index:90; overflow-y:auto; text-shadow:0 1px 2px rgba(0,0,0,0.8); overflow-x:hidden; width:clamp(150px, 40vw, 190px); width:clamp(150px, 40cqw, 190px); }
|
|
6424
6485
|
.dock.open { opacity:1; pointer-events:auto; border-color:rgba(0,230,118,0.3); }
|
|
6425
6486
|
.btn { background:rgba(255,255,255,0.06); color:var(--txt); border:1px solid transparent; padding:9px 12px; border-radius:9px; cursor:pointer; display:flex; align-items:center; justify-content:center; gap:8px;
|
|
6426
6487
|
font-weight:600; font-size:13px; transition:background-color 0.2s, border-color 0.2s; touch-action:manipulation; width:100%; text-align:center; }
|
|
@@ -6519,7 +6580,7 @@
|
|
|
6519
6580
|
.sync-bubble.visible { opacity:1; transform:translate(-50%,0); }
|
|
6520
6581
|
/* bubbles */
|
|
6521
6582
|
.nx-bubbles { position:absolute; top:calc(64px + env(safe-area-inset-top, 0px)); left:calc(12px + env(safe-area-inset-left, 0px)); z-index:1950; display:flex; flex-direction:column; gap:8px; width:min(300px, calc(100% - 24px)); pointer-events:none; }
|
|
6522
|
-
.nx-bubble { pointer-events:auto; display:block; width:100%; text-align:left; border:none; cursor:pointer; color:#fff; font:inherit; background:rgba(18,20,26,0.
|
|
6583
|
+
.nx-bubble { pointer-events:auto; display:block; width:100%; text-align:left; border:none; cursor:pointer; color:#fff; font:inherit; background:rgba(18,20,26,0.52); -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); text-shadow:0 1px 2px rgba(0,0,0,0.8);
|
|
6523
6584
|
border-radius:16px 16px 16px 6px; padding:9px 12px 10px; box-shadow:0 8px 24px rgba(0,0,0,0.45); border-left:4px solid var(--c, #69f0ae); opacity:0; transform:translateX(-24px) scale(0.96); transition:opacity 0.25s ease, transform 0.25s ease; }
|
|
6524
6585
|
.nx-bubble.in { opacity:1; transform:none; }
|
|
6525
6586
|
.nx-bubble.out { opacity:0; transform:translateX(-24px); }
|
|
@@ -6528,7 +6589,7 @@
|
|
|
6528
6589
|
.nx-bubble-text { margin-top:3px; font-size:13.5px; line-height:1.4; overflow:hidden; display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow-wrap:anywhere; }
|
|
6529
6590
|
/* talk: speech bubbles */
|
|
6530
6591
|
.nx-bubble.nx-talk { display:flex; align-items:flex-start; gap:9px; width:auto; max-width:100%; align-self:flex-start; border-left:none; border-radius:18px 18px 18px 6px; padding:8px 12px 9px 8px;
|
|
6531
|
-
background:linear-gradient(135deg, color-mix(in srgb, var(--c, #69f0ae) 22%, rgba(18,20,26,0.
|
|
6592
|
+
background:linear-gradient(135deg, color-mix(in srgb, var(--c, #69f0ae) 22%, rgba(18,20,26,0.58)), rgba(18,20,26,0.5)); box-shadow:0 8px 24px rgba(0,0,0,0.45), 0 0 0 1px color-mix(in srgb, var(--c, #69f0ae) 45%, transparent) inset; transform:translateX(-18px) scale(0.9); transform-origin:left bottom; transition:opacity 0.28s ease, transform 0.35s cubic-bezier(.2,1.4,.4,1); }
|
|
6532
6593
|
.nx-bubble.nx-talk.in { transform:none; }
|
|
6533
6594
|
.nx-bubble.nx-talk.out { opacity:0; transform:translateY(-8px) scale(0.92); transition:opacity 0.3s ease, transform 0.3s ease; }
|
|
6534
6595
|
.nx-bubble.nx-talk.mine { align-self:flex-start; border-radius:18px 18px 6px 18px; opacity:0; background:rgba(18,20,26,0.8); }
|
|
@@ -6544,8 +6605,30 @@
|
|
|
6544
6605
|
.nx-dots i:nth-child(2) { animation-delay:0.15s; } .nx-dots i:nth-child(3) { animation-delay:0.3s; }
|
|
6545
6606
|
@keyframes nxDot { 0%,60%,100% { transform:translateY(0); opacity:0.45; } 30% { transform:translateY(-4px); opacity:1; } }
|
|
6546
6607
|
@keyframes nxFadeIn { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }
|
|
6608
|
+
.nx-mode-card { position:absolute; left:50%; top:calc(64px + env(safe-area-inset-top, 0px)); transform:translate(-50%, -10px); z-index:2066; width:min(380px, calc(100% - 28px)); padding:11px 12px 11px; border-radius:16px;
|
|
6609
|
+
background:rgba(16,18,24,0.62); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); box-shadow:0 12px 30px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.14) inset; color:#fff; text-shadow:0 1px 2px rgba(0,0,0,0.8);
|
|
6610
|
+
opacity:0; transition:opacity 0.25s ease, transform 0.25s ease; pointer-events:auto; }
|
|
6611
|
+
.nx-mode-card.in { opacity:1; transform:translate(-50%, 0); }
|
|
6612
|
+
.nx-mode-head { display:flex; align-items:center; gap:7px; font-weight:800; font-size:14px; padding-right:26px; }
|
|
6613
|
+
.nx-mode-sub { margin-top:4px; font-size:12.5px; line-height:1.4; opacity:0.85; }
|
|
6614
|
+
.nx-mode-row { display:flex; gap:7px; margin-top:9px; flex-wrap:wrap; }
|
|
6615
|
+
.nx-mode-btn { flex:1 1 auto; border:1px solid rgba(255,255,255,0.2); background:rgba(255,255,255,0.1); color:#fff; border-radius:10px; padding:8px 10px; font-size:12.5px; font-weight:800; cursor:pointer; font-family:inherit; text-shadow:none; }
|
|
6616
|
+
.nx-mode-btn.primary { background:#69f0ae; border-color:#69f0ae; color:#061009; }
|
|
6617
|
+
.nx-mode-x { position:absolute; top:8px; right:8px; width:24px; height:24px; border:none; border-radius:50%; background:rgba(255,255,255,0.12); color:#fff; font-size:11px; cursor:pointer; }
|
|
6618
|
+
.nx-next { position:absolute; right:calc(18px + env(safe-area-inset-right, 0px)); bottom:calc(120px + env(safe-area-inset-bottom, 0px)); z-index:2065; display:flex; align-items:center; gap:10px; padding:8px 8px 8px 8px; border-radius:16px;
|
|
6619
|
+
background:rgba(16,18,24,0.6); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); box-shadow:0 10px 28px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.14) inset; color:#fff; max-width:min(360px, calc(100% - 36px));
|
|
6620
|
+
opacity:0; transform:translateY(12px) scale(0.97); transition:opacity 0.25s ease, transform 0.25s ease; pointer-events:auto; text-shadow:0 1px 2px rgba(0,0,0,0.8); }
|
|
6621
|
+
.nx-next.in { opacity:1; transform:none; }
|
|
6622
|
+
.nx-next-go { position:relative; flex:0 0 auto; width:46px; height:46px; border:none; border-radius:50%; background:#fff; color:#111; cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:18px; text-shadow:none; }
|
|
6623
|
+
.nx-next-ring { position:absolute; inset:-4px; border-radius:50%; background:conic-gradient(#69f0ae calc(var(--p, 0) * 360deg), rgba(255,255,255,0.18) 0); -webkit-mask:radial-gradient(circle, transparent 25px, #000 26px); mask:radial-gradient(circle, transparent 25px, #000 26px); opacity:0; transition:opacity 0.2s; }
|
|
6624
|
+
.nx-next.counting .nx-next-ring { opacity:1; }
|
|
6625
|
+
.nx-next-ic { position:relative; }
|
|
6626
|
+
.nx-next-text { min-width:0; cursor:pointer; }
|
|
6627
|
+
.nx-next-k { font-size:11px; font-weight:800; opacity:0.75; text-transform:uppercase; letter-spacing:0.04em; }
|
|
6628
|
+
.nx-next-l { font-size:14px; font-weight:800; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
6629
|
+
.nx-next-x { flex:0 0 auto; width:28px; height:28px; border:none; border-radius:50%; background:rgba(255,255,255,0.12); color:#fff; cursor:pointer; font-size:12px; }
|
|
6547
6630
|
.nx-compose { position:absolute; left:50%; bottom:calc(112px + env(safe-area-inset-bottom, 0px)); z-index:2060; width:min(520px, calc(100% - 24px)); transform:translate(-50%, 16px) scale(0.96); opacity:0; pointer-events:none;
|
|
6548
|
-
background:rgba(16,18,24,0.
|
|
6631
|
+
background:rgba(16,18,24,0.58); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); border-radius:18px; padding:8px 8px 9px; text-shadow:0 1px 2px rgba(0,0,0,0.75); box-shadow:0 14px 36px rgba(0,0,0,0.55), 0 0 0 1px color-mix(in srgb, var(--c, #69f0ae) 50%, transparent);
|
|
6549
6632
|
transition:opacity 0.22s ease, transform 0.25s cubic-bezier(.2,1.3,.4,1); display:flex; flex-direction:column; gap:6px; }
|
|
6550
6633
|
.nx-compose.open { opacity:1; transform:translate(-50%, 0) scale(1); pointer-events:auto; }
|
|
6551
6634
|
.nx-compose-head { display:flex; align-items:center; gap:6px; padding:0 2px 0 6px; }
|
|
@@ -6555,6 +6638,10 @@
|
|
|
6555
6638
|
.nx-compose-row { display:flex; gap:6px; }
|
|
6556
6639
|
.nx-compose-input { flex:1; min-width:0; background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.14); color:#fff; border-radius:999px; padding:9px 14px; font-size:16px; font-family:inherit; outline:none; }
|
|
6557
6640
|
.nx-compose-input:focus { border-color:var(--c, #69f0ae); }
|
|
6641
|
+
.nx-compose-x.nx-compose-full { width:auto; padding:0 10px 0 8px; border-radius:999px; display:inline-flex; align-items:center; gap:5px; font-size:12px; font-weight:800; background:rgba(255,255,255,0.12); border:1px solid rgba(255,255,255,0.18); }
|
|
6642
|
+
.nx-compose-x.nx-compose-full:hover { background:rgba(255,255,255,0.2); }
|
|
6643
|
+
.nx-hist-count:empty { display:none; }
|
|
6644
|
+
.nx-hist-count { min-width:16px; height:16px; padding:0 4px; border-radius:8px; background:var(--c, #69f0ae); color:#061009; font-size:10.5px; line-height:16px; text-align:center; }
|
|
6558
6645
|
.nx-compose-send { flex:0 0 auto; width:40px; height:40px; border:none; border-radius:50%; background:var(--c, #69f0ae); color:#061009; font-size:16px; font-weight:900; cursor:pointer; }
|
|
6559
6646
|
.nx-compose-send:active, .nx-compose-x:active { transform:scale(0.92); }
|
|
6560
6647
|
.cc-vhud { position:absolute; top:50%; right:calc(28px + env(safe-area-inset-right, 0px)); transform:translateY(-50%) scale(0.92); z-index:2070; display:flex; flex-direction:column; align-items:center; gap:8px;
|
|
@@ -6584,6 +6671,7 @@
|
|
|
6584
6671
|
.nx-cover.compact .nx-cover-actions { bottom:8px; } .nx-cover.compact .nx-cover-btn { padding:5px 10px; font-size:11.5px; }
|
|
6585
6672
|
.react-btn.together-btn.cover-btn { box-shadow:0 0 0 1.5px rgba(255,138,128,0.65) inset; }
|
|
6586
6673
|
/* profile & chat extras */
|
|
6674
|
+
.nx-logo { width:20px; height:20px; border-radius:6px; vertical-align:-4px; margin-right:7px; box-shadow:0 2px 8px rgba(91,46,255,0.45); }
|
|
6587
6675
|
.nx-me-dot { background:var(--c, #69f0ae) !important; box-shadow:0 0 0 2px rgba(255,255,255,0.25), 0 0 10px var(--c, #69f0ae); }
|
|
6588
6676
|
.nx-profile { display:flex; flex-direction:column; gap:7px; padding:6px 4px 2px; }
|
|
6589
6677
|
.nx-profile-title { font-size:11.5px; font-weight:800; color:rgba(255,255,255,0.7); padding-left:4px; }
|
|
@@ -6596,6 +6684,8 @@
|
|
|
6596
6684
|
.nx-latency-label { font-weight:700; }
|
|
6597
6685
|
.nx-latency-range { flex:1 1 140px; accent-color:var(--c, #69f0ae); }
|
|
6598
6686
|
.nx-latency-live { flex-basis:100%; font-size:11px; opacity:0.65; }
|
|
6687
|
+
.nx-talk-pending { opacity:0.45; animation:nxPend 1s ease-in-out infinite alternate; }
|
|
6688
|
+
@keyframes nxPend { from { opacity:0.25; } to { opacity:0.6; } }
|
|
6599
6689
|
.nx-talk-orig { margin-top:3px; font-size:11.5px; opacity:0.6; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:240px; }
|
|
6600
6690
|
.nx-quick-field { flex:1 1 auto; min-width:120px; padding:6px 12px; font-size:14px; }
|
|
6601
6691
|
.quick-edit { opacity:0.75; }
|
|
@@ -6669,6 +6759,8 @@
|
|
|
6669
6759
|
.rx { position:absolute; z-index:50; pointer-events:none !important; will-change:transform, opacity; line-height:1; user-select:none; -webkit-user-select:none; }
|
|
6670
6760
|
.rx-emoji { filter:drop-shadow(0 3px 6px rgba(0,0,0,0.45)) drop-shadow(0 0 10px rgba(255,255,255,0.18)); opacity:0; }
|
|
6671
6761
|
.rx-mini { opacity:0; filter:drop-shadow(0 1px 2px rgba(0,0,0,0.5)); }
|
|
6762
|
+
.rx-crumb { width:5px; height:5px; border-radius:2px; background:#c68a4e; box-shadow:0 0 0 1px rgba(90,50,20,0.35); opacity:0; }
|
|
6763
|
+
.rx-steam { width:6px; height:14px; border-radius:50%; background:radial-gradient(ellipse at center, rgba(255,255,255,0.85), rgba(255,255,255,0)); filter:blur(1.5px); opacity:0; }
|
|
6672
6764
|
.rx-spark { width:7px; height:7px; border-radius:50%; background:#fff; box-shadow:0 0 6px 2px var(--c, #69f0ae), 0 0 14px 4px var(--c, #69f0ae); opacity:0; }
|
|
6673
6765
|
.rx-ring { width:60px; height:60px; border-radius:50%; border:3px solid var(--c, #69f0ae); box-shadow:0 0 18px var(--c, #69f0ae), inset 0 0 12px var(--c, #69f0ae); }
|
|
6674
6766
|
.rx-glow { top:0 !important; bottom:0; width:min(90px, 14%); opacity:0; }
|
|
@@ -6697,8 +6789,9 @@
|
|
|
6697
6789
|
.cc-btn.cc-mode { gap:6px; padding:0 12px 0 10px; background:rgba(255,255,255,0.12); font-size:12px; }
|
|
6698
6790
|
.cc-btn.cc-mode:hover { background:rgba(255,255,255,0.22); }
|
|
6699
6791
|
.cc-mode-label { white-space:nowrap; }
|
|
6700
|
-
.cc-scrim { position:absolute; inset:0; z-index:59; pointer-events:none; background:
|
|
6701
|
-
|
|
6792
|
+
.cc-scrim { position:absolute; inset:0; z-index:59; pointer-events:none; background:transparent; transition:opacity 0.35s ease; }
|
|
6793
|
+
/* The picture stays fully clear while the controls show; the controls carry their own shadow. */
|
|
6794
|
+
.cinema-chrome .cc-top, .cinema-chrome .cc-bottom, .cinema-chrome .cc-center { filter:drop-shadow(0 1px 2px rgba(0,0,0,0.85)) drop-shadow(0 0 8px rgba(0,0,0,0.45)); }
|
|
6702
6795
|
.cc-top, .cc-bottom, .cc-center { position:absolute; left:0; right:0; z-index:75; pointer-events:auto; transition:opacity 0.3s ease, transform 0.3s ease; }
|
|
6703
6796
|
.cc-top { pointer-events:none; }
|
|
6704
6797
|
.cc-top .cc-btn { pointer-events:auto; }
|
|
@@ -6792,7 +6885,7 @@
|
|
|
6792
6885
|
.nexus-container.cinema-on .sub-overlay-container { transition:bottom 0.35s ease, opacity 0.3s ease; }
|
|
6793
6886
|
.cinema-chrome.touch .cc-back, .cinema-chrome.touch .cc-fwd, .cinema-chrome.touch .cc-play { display:none; }
|
|
6794
6887
|
.cinema-chrome.touch .cc-seek { height:28px; }
|
|
6795
|
-
@container nexus (max-width: 560px) { .cc-
|
|
6888
|
+
@container nexus (max-width: 560px) { .cc-fit, .cinema-chrome:not(.site-mode) .cc-mode-label { display:none; } .cc-btn.cc-mode { padding:0 8px; } .cc-btn { min-width:36px; padding:0 6px; } .cc-time { font-size:12px; margin-left:2px; } }
|
|
6796
6889
|
@container nexus (max-width: 380px) { .cc-ambient { display:none; } }
|
|
6797
6890
|
@container nexus (max-width: 600px) {
|
|
6798
6891
|
.dock { padding:8px; gap:5px; }
|
|
@@ -6878,6 +6971,8 @@
|
|
|
6878
6971
|
const btnSyncStatus = mk('nxu-sync-status', '📡 ' + t('sync'));
|
|
6879
6972
|
const btnInvite = mk('nxu-invite', '👥 ' + t('invite'), t('inviteTitle'));
|
|
6880
6973
|
const btnCinema = mk('nxu-cinema', '🍿 ' + t('cinema'), t('cinemaTitle'));
|
|
6974
|
+
const btnAutoCinema = mk('nxu-auto-cinema', '');
|
|
6975
|
+
btnAutoCinema.classList.add('subtle');
|
|
6881
6976
|
const btnPiP = mk('nxu-pip', '📺 PiP');
|
|
6882
6977
|
const btnRate = mk('nxu-rate', '⏩ 1x', t('rateTitle'));
|
|
6883
6978
|
// Talking happens in speech bubbles and quick ink now: the menu opens those directly
|
|
@@ -6941,7 +7036,8 @@
|
|
|
6941
7036
|
// Connect panel
|
|
6942
7037
|
const manualModal = createEl('div', 'window-frame');
|
|
6943
7038
|
manualModal.id = 'manual-modal';
|
|
6944
|
-
const manualHeader = createWindowHeader('
|
|
7039
|
+
const manualHeader = createWindowHeader('NexusSync', [{ className: 'close-btn', text: '✖' }]);
|
|
7040
|
+
manualHeader.firstElementChild?.prepend(createEl('img', 'nx-logo', '', { src: NXU_ICON, alt: '', width: '20', height: '20' }));
|
|
6945
7041
|
const manualBody = createEl('div', 'manual-body');
|
|
6946
7042
|
const hostBtn = createEl('button', 'btn', '🏠 ' + t('createRoom'));
|
|
6947
7043
|
const pinDisplay = createEl('div', 'pin-display', '------');
|
|
@@ -6989,7 +7085,8 @@
|
|
|
6989
7085
|
const toast = createEl('div', 'toast');
|
|
6990
7086
|
toast.setAttribute('role', 'status');
|
|
6991
7087
|
|
|
6992
|
-
|
|
7088
|
+
// Sketching and chat live in the reaction bar (🖍️ 💬); the menu does not repeat them.
|
|
7089
|
+
dock.append(btnFindMedia, btnLink, btnInvite, btnSyncStatus, btnCinema, btnAutoCinema, btnPiP, btnRate, btnBookmark, btnTranslate, btnSubLog, btnDebug, btnHideSite);
|
|
6993
7090
|
uiWrapper.append(dock, reactPill, fab);
|
|
6994
7091
|
nexusContainer.append(drawCanvas, uiWrapper, chatPanel, subLogPanel, manualModal, transModal, toast, debugPanel);
|
|
6995
7092
|
shadow.appendChild(nexusContainer);
|
|
@@ -7000,7 +7097,7 @@
|
|
|
7000
7097
|
['keyup', 'keypress'].forEach(evt => nexusContainer.addEventListener(evt, e => { if (isEditableTarget(e.composedPath()[0])) e.stopPropagation(); }));
|
|
7001
7098
|
|
|
7002
7099
|
uiElements = {
|
|
7003
|
-
uiWrapper, fab, reactPill, dock, btnFindMedia, btnLink, btnSyncStatus, btnTranslate, btnCinema, btnPiP, btnRate, btnDraw, btnBookmark, btnChat, btnSubLog,
|
|
7100
|
+
uiWrapper, fab, reactPill, dock, btnFindMedia, btnLink, btnSyncStatus, btnTranslate, btnCinema, btnAutoCinema, btnPiP, btnRate, btnDraw, btnBookmark, btnChat, btnSubLog,
|
|
7004
7101
|
btnDebug, btnHideSite, chatPanel, chatMessages, chatInput, chatJumpBtn, subLogPanel, subLogMessages,
|
|
7005
7102
|
subLogJumpBtn, drawCanvas, manualModal, transModal, toast, debugJumpBtn, syncBubble: null,
|
|
7006
7103
|
pinError, guestInput, pinHint, pinDisplay, pinCopyBtn, hostBtn, connectBtn, btnInvite, typingRow, nickInput
|
|
@@ -7235,6 +7332,7 @@
|
|
|
7235
7332
|
};
|
|
7236
7333
|
|
|
7237
7334
|
btnCinema.onclick = () => { triggerHaptic(); CINEMA.toggle(); };
|
|
7335
|
+
btnAutoCinema.onclick = () => { triggerHaptic(); AUTO_CINEMA.setSite(!AUTO_CINEMA.enabled()); };
|
|
7238
7336
|
btnPiP.onclick = async () => {
|
|
7239
7337
|
let video = STATE.video;
|
|
7240
7338
|
if (!video || video.readyState === 0) {
|
|
@@ -7462,7 +7560,7 @@
|
|
|
7462
7560
|
},
|
|
7463
7561
|
publish() {
|
|
7464
7562
|
try {
|
|
7465
|
-
if (ydoc && yPresence && STATE.handshakeVerified) ydoc.transact(() => yPresence.set(STATE.userId, { ts: Date.now(), color: STATE.color, viewer: !!STATE.isViewer, nick: STATE.nickname || '', v: NXU_VERSION, r: NXU_RANK }), 'local');
|
|
7563
|
+
if (ydoc && yPresence && STATE.handshakeVerified) ydoc.transact(() => yPresence.set(STATE.userId, { ts: Date.now(), color: STATE.color, viewer: !!STATE.isViewer, nick: STATE.nickname || '', v: NXU_VERSION, r: NXU_RANK, sess: NXU_SESSION, hid: !!document.hidden }), 'local');
|
|
7466
7564
|
} catch (_) { }
|
|
7467
7565
|
},
|
|
7468
7566
|
// Small editor: name + colour swatches + any colour.
|
|
@@ -7578,25 +7676,43 @@
|
|
|
7578
7676
|
});
|
|
7579
7677
|
},
|
|
7580
7678
|
// → { text, from } or null when no translation is needed / possible.
|
|
7679
|
+
_pending: new Map(),
|
|
7581
7680
|
async translate(text) {
|
|
7582
7681
|
const tl = myLanguage();
|
|
7583
7682
|
const key = tl + '\n' + text;
|
|
7584
7683
|
if (this._cache.has(key)) return this._cache.get(key);
|
|
7585
7684
|
if (!/[\p{L}]{2,}/u.test(text)) return null; // emoji, numbers, "ㅋ"
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7685
|
+
// The bubble and the room chat ask for the same message at the same moment.
|
|
7686
|
+
if (this._pending.has(key)) return this._pending.get(key);
|
|
7687
|
+
const job = this._fetch(text, tl).then((result) => {
|
|
7688
|
+
// Only real answers are remembered: a network hiccup (slow iPad link, a
|
|
7689
|
+
// blocked request) must not leave that message untranslated for good.
|
|
7690
|
+
if (result !== undefined) {
|
|
7691
|
+
this._cache.set(key, result);
|
|
7692
|
+
if (this._cache.size > 200) this._cache.delete(this._cache.keys().next().value);
|
|
7693
|
+
}
|
|
7694
|
+
return result || null;
|
|
7695
|
+
}).finally(() => this._pending.delete(key));
|
|
7696
|
+
this._pending.set(key, job);
|
|
7697
|
+
return job;
|
|
7698
|
+
},
|
|
7699
|
+
// → { text, from } | null (no translation needed) | undefined (failed: try again later)
|
|
7700
|
+
async _fetch(text, tl) {
|
|
7701
|
+
const g = code => (code === 'zh' ? 'zh-CN' : code);
|
|
7702
|
+
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${g(tl)}&dt=t&q=${encodeURIComponent(text.slice(0, 500))}`;
|
|
7703
|
+
// Through the userscript manager first, then directly (some iPad setups only allow one).
|
|
7704
|
+
for (const viaFetch of [false, true]) {
|
|
7705
|
+
try {
|
|
7706
|
+
const res = await _httpRequest({ url, timeout: 9000, viaFetch });
|
|
7707
|
+
if (res.status !== 200) continue;
|
|
7591
7708
|
const data = JSON.parse(res.text);
|
|
7592
7709
|
const out = Array.isArray(data?.[0]) ? data[0].map(x => (x && x[0]) || '').join('').trim() : '';
|
|
7593
7710
|
const from = baseLang(String(data?.[2] || ''));
|
|
7594
|
-
if (out && from && from !== baseLang(tl) && out.toLowerCase() !== text.trim().toLowerCase())
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
return result;
|
|
7711
|
+
if (out && from && from !== baseLang(tl) && out.toLowerCase() !== text.trim().toLowerCase()) return { text: out, from };
|
|
7712
|
+
return null;
|
|
7713
|
+
} catch (_) { }
|
|
7714
|
+
}
|
|
7715
|
+
return undefined;
|
|
7600
7716
|
}
|
|
7601
7717
|
};
|
|
7602
7718
|
|
|
@@ -7626,17 +7742,21 @@
|
|
|
7626
7742
|
const reply = createEl('span', 'nx-talk-reply', '↩');
|
|
7627
7743
|
card.append(reply);
|
|
7628
7744
|
}
|
|
7629
|
-
|
|
7745
|
+
let timer = null, left = Math.max(4200, Math.min(11000, 3500 + text.length * 70)), startedAt = 0;
|
|
7746
|
+
if (!mine && CHAT_TR.enabled() && /[\p{L}]{2,}/u.test(text)) {
|
|
7747
|
+
const pend = createEl('span', 'nx-talk-orig nx-talk-pending', '🌐 …');
|
|
7748
|
+
body.querySelector('.nx-bubble-text').after(pend);
|
|
7630
7749
|
CHAT_TR.translate(text).then((tr) => {
|
|
7631
|
-
|
|
7750
|
+
pend.remove();
|
|
7751
|
+
if (!tr || !card.isConnected || card.classList.contains('out')) return;
|
|
7632
7752
|
const main = body.querySelector('.nx-bubble-text');
|
|
7633
7753
|
main.textContent = tr.text;
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
left
|
|
7754
|
+
main.after(createEl('span', 'nx-talk-orig', '🌐 ' + text));
|
|
7755
|
+
// Time to read the translation too (the bubble was already counting down).
|
|
7756
|
+
if (startedAt) { clearTimeout(timer); left = Math.max(left - (Date.now() - startedAt), 0) + 2500 + tr.text.length * 40; run(); }
|
|
7757
|
+
else left += 2500;
|
|
7637
7758
|
});
|
|
7638
7759
|
}
|
|
7639
|
-
let timer = null, left = Math.max(4200, Math.min(11000, 3500 + text.length * 70)), startedAt = 0;
|
|
7640
7760
|
const close = () => { clearTimeout(timer); card.classList.add('out'); setTimeout(() => card.remove(), 300); };
|
|
7641
7761
|
const run = () => { startedAt = Date.now(); timer = setTimeout(close, left); };
|
|
7642
7762
|
const hold = () => { clearTimeout(timer); left = Math.max(1500, left - (Date.now() - startedAt)); };
|
|
@@ -7678,7 +7798,8 @@
|
|
|
7678
7798
|
const to = createEl('span', 'nx-compose-to');
|
|
7679
7799
|
const x = createEl('button', 'nx-compose-x', '✕', { type: 'button', title: t('talkClose'), 'aria-label': t('talkClose') });
|
|
7680
7800
|
x.onclick = (e) => { e.stopPropagation(); this.close(); };
|
|
7681
|
-
const full = createEl('button', 'nx-compose-x nx-compose-full', '
|
|
7801
|
+
const full = createEl('button', 'nx-compose-x nx-compose-full', '', { type: 'button', title: t('talkFull'), 'aria-label': t('talkFull') });
|
|
7802
|
+
full.append(createEl('span', 'nx-hist-ic', '🗂'), createEl('span', 'nx-hist-label', t('talkHistory')), createEl('span', 'nx-hist-count'));
|
|
7682
7803
|
full.onclick = (e) => { e.stopPropagation(); this.close(); openChatPanel(); };
|
|
7683
7804
|
const me = createEl('button', 'nx-compose-x nx-me-dot', '', { type: 'button', title: t('profileTitle'), 'aria-label': t('profileTitle') });
|
|
7684
7805
|
me.style.setProperty('--c', STATE.color);
|
|
@@ -7712,6 +7833,10 @@
|
|
|
7712
7833
|
const to = this._composer.querySelector('.nx-compose-to');
|
|
7713
7834
|
to.textContent = replyTo ? t('talkReplyTo', { name: replyTo }) : '💬 ' + t('talkTitle');
|
|
7714
7835
|
this._composer.style.setProperty('--c', color || STATE.color || '#69f0ae');
|
|
7836
|
+
// How much history the room chat holds (shown on the "History" pill).
|
|
7837
|
+
const n = (() => { try { return yChat ? yChat.length : 0; } catch (_) { return 0; } })();
|
|
7838
|
+
const cnt = this._composer.querySelector('.nx-hist-count');
|
|
7839
|
+
if (cnt) cnt.textContent = n ? (n > 99 ? '99+' : String(n)) : '';
|
|
7715
7840
|
this._composer.classList.add('open');
|
|
7716
7841
|
this._fitKeyboard();
|
|
7717
7842
|
if (!this._vvBound && window.visualViewport) {
|
|
@@ -8026,6 +8151,253 @@
|
|
|
8026
8151
|
}
|
|
8027
8152
|
};
|
|
8028
8153
|
|
|
8154
|
+
// ───────────────────────── Automatic cinema
|
|
8155
|
+
// Opening a page that is all about one video (an episode, a movie — not a feed with many
|
|
8156
|
+
// posts) switches to cinema mode as soon as the video is ready. It keeps the site's own
|
|
8157
|
+
// player, because subtitles and servers are often picked there; a small card says which
|
|
8158
|
+
// player is in use and switches to NexusSync's player in one tap. Per site on/off.
|
|
8159
|
+
const AUTO_CINEMA = {
|
|
8160
|
+
_doneFor: '',
|
|
8161
|
+
_auto: false,
|
|
8162
|
+
_card: null,
|
|
8163
|
+
FEED_HOSTS: /(^|\.)(reddit\.com|x\.com|twitter\.com|facebook\.com|instagram\.com|tiktok\.com|threads\.net|9gag\.com|imgur\.com|tumblr\.com|pinterest\.[a-z.]+|linkedin\.com|discord\.com|dcinside\.com|fmkorea\.com|theqoo\.net|ruliweb\.com|clien\.net|naver\.com|daum\.net)$/i,
|
|
8164
|
+
_sites() { const v = STORE.get('nxu_auto_cinema_sites', {}); return v && typeof v === 'object' ? v : {}; },
|
|
8165
|
+
enabled() {
|
|
8166
|
+
const v = this._sites()[HOST];
|
|
8167
|
+
if (v === true || v === false) return v;
|
|
8168
|
+
return !this.FEED_HOSTS.test(HOST);
|
|
8169
|
+
},
|
|
8170
|
+
setSite(on) {
|
|
8171
|
+
const all = { ...this._sites(), [HOST]: !!on };
|
|
8172
|
+
const keys = Object.keys(all);
|
|
8173
|
+
if (keys.length > 300) delete all[keys[0]];
|
|
8174
|
+
STORE.set('nxu_auto_cinema_sites', all);
|
|
8175
|
+
this.paintButton();
|
|
8176
|
+
showToast(t(on ? 'autoCinemaOnSite' : 'autoCinemaOffSite', { site: HOST }));
|
|
8177
|
+
},
|
|
8178
|
+
paintButton() {
|
|
8179
|
+
const b = uiElements.btnAutoCinema;
|
|
8180
|
+
if (!b) return;
|
|
8181
|
+
const on = this.enabled();
|
|
8182
|
+
b.textContent = '✨ ' + t(on ? 'autoCinemaBtnOn' : 'autoCinemaBtnOff');
|
|
8183
|
+
b.classList.toggle('active', on);
|
|
8184
|
+
},
|
|
8185
|
+
// One real video on the page, big enough, long enough — not a feed.
|
|
8186
|
+
_singleMedia() {
|
|
8187
|
+
if (/\/shorts\//.test(location.pathname) || /\/reel(s)?\//.test(location.pathname)) return false;
|
|
8188
|
+
if (document.querySelectorAll('article').length >= 4) return false;
|
|
8189
|
+
const doc = document.scrollingElement || document.documentElement;
|
|
8190
|
+
if (doc && doc.scrollHeight > window.innerHeight * 10) return false;
|
|
8191
|
+
let big = 0;
|
|
8192
|
+
for (const v of document.querySelectorAll('video')) {
|
|
8193
|
+
const r = v.getBoundingClientRect();
|
|
8194
|
+
if (r.width >= 200 && r.height >= 110) big++;
|
|
8195
|
+
}
|
|
8196
|
+
for (const [ifr] of VIDEO_DETECTOR.frameReports) {
|
|
8197
|
+
const r = ifr.getBoundingClientRect();
|
|
8198
|
+
if (r.width >= 200 && r.height >= 110) big++;
|
|
8199
|
+
}
|
|
8200
|
+
if (big > 1) return false;
|
|
8201
|
+
const info = currentMediaInfo();
|
|
8202
|
+
if (!info) return false;
|
|
8203
|
+
const r = info.el.getBoundingClientRect();
|
|
8204
|
+
if (r.width < Math.min(420, window.innerWidth * 0.6)) return false;
|
|
8205
|
+
return Number.isFinite(info.duration) && info.duration >= 90;
|
|
8206
|
+
},
|
|
8207
|
+
tick() {
|
|
8208
|
+
if (!IS_TOP || STATE.retired || STATE.isCinema || STATE.pendingCinema || document.hidden) return;
|
|
8209
|
+
const key = location.href.split('#')[0];
|
|
8210
|
+
if (this._doneFor === key || !this.enabled() || STORE.get('nxu_hide_fab_' + HOST, false)) return;
|
|
8211
|
+
if (!(STATE.video || STATE.cinemaIframe)) return;
|
|
8212
|
+
if (STATE.video && STATE.video.readyState < 1) return;
|
|
8213
|
+
if (!this._singleMedia()) return;
|
|
8214
|
+
this._doneFor = key;
|
|
8215
|
+
this._auto = true;
|
|
8216
|
+
CINEMA.setControls('site', { save: false });
|
|
8217
|
+
CINEMA.set(true, { silent: true });
|
|
8218
|
+
if (!STATE.isCinema) { this._auto = false; STATE.controlsOverride = null; }
|
|
8219
|
+
},
|
|
8220
|
+
onEnter() {
|
|
8221
|
+
const auto = this._auto;
|
|
8222
|
+
this._auto = false;
|
|
8223
|
+
setTimeout(() => this._showCard(auto), 400);
|
|
8224
|
+
},
|
|
8225
|
+
onExit() {
|
|
8226
|
+
this._doneFor = location.href.split('#')[0]; // left on purpose: not again on this page
|
|
8227
|
+
this._hideCard();
|
|
8228
|
+
},
|
|
8229
|
+
_hideCard() {
|
|
8230
|
+
const c = this._card;
|
|
8231
|
+
this._card = null;
|
|
8232
|
+
clearTimeout(this._cardTimer);
|
|
8233
|
+
if (c) { c.classList.remove('in'); setTimeout(() => c.remove(), 260); }
|
|
8234
|
+
},
|
|
8235
|
+
// Which player is in use, with a one-tap switch (and the per-site switch after an automatic start).
|
|
8236
|
+
_showCard(auto) {
|
|
8237
|
+
if (!STATE.isCinema || !IS_TOP) return;
|
|
8238
|
+
const container = getContainer();
|
|
8239
|
+
if (!container) return;
|
|
8240
|
+
this._hideCard();
|
|
8241
|
+
const site = CINEMA_UI.controlsMode() === 'site';
|
|
8242
|
+
const card = createEl('div', 'nx-mode-card');
|
|
8243
|
+
const head = createEl('div', 'nx-mode-head');
|
|
8244
|
+
head.append(createEl('span', 'nx-mode-ic', site ? '🎛️' : '🍿'), createEl('span', 'nx-mode-title', t(site ? 'modeSitePlayer' : 'modeNexusPlayer')));
|
|
8245
|
+
const sub = createEl('div', 'nx-mode-sub', t(site ? (auto ? 'modeSiteHintAuto' : 'modeSiteHint') : 'modeNexusHint'));
|
|
8246
|
+
const row = createEl('div', 'nx-mode-row');
|
|
8247
|
+
const sw = createEl('button', 'nx-mode-btn primary', t(site ? 'modeUseNexus' : 'modeUseSite'), { type: 'button' });
|
|
8248
|
+
sw.onclick = (e) => {
|
|
8249
|
+
e.stopPropagation();
|
|
8250
|
+
const next = CINEMA_UI.controlsMode() === 'site' ? 'nexus' : 'site';
|
|
8251
|
+
CINEMA_UI._resetGestures?.();
|
|
8252
|
+
CINEMA.setControls(next, { save: false });
|
|
8253
|
+
CINEMA_UI.sync();
|
|
8254
|
+
this._hideCard();
|
|
8255
|
+
setTimeout(() => this._showCard(false), 350);
|
|
8256
|
+
};
|
|
8257
|
+
row.appendChild(sw);
|
|
8258
|
+
if (auto) {
|
|
8259
|
+
const off = createEl('button', 'nx-mode-btn', t('autoCinemaStopSite'), { type: 'button' });
|
|
8260
|
+
off.onclick = (e) => { e.stopPropagation(); this.setSite(false); this._hideCard(); CINEMA.set(false, { silent: true }); };
|
|
8261
|
+
row.appendChild(off);
|
|
8262
|
+
}
|
|
8263
|
+
const x = createEl('button', 'nx-mode-x', '✕', { type: 'button', 'aria-label': t('talkClose') });
|
|
8264
|
+
x.onclick = (e) => { e.stopPropagation(); this._hideCard(); };
|
|
8265
|
+
card.append(x, head, sub, row);
|
|
8266
|
+
['pointerdown', 'click', 'touchstart'].forEach(ev => card.addEventListener(ev, (e) => e.stopPropagation()));
|
|
8267
|
+
container.appendChild(card);
|
|
8268
|
+
this._card = card;
|
|
8269
|
+
requestAnimationFrame(() => card.classList.add('in'));
|
|
8270
|
+
this._cardTimer = setTimeout(() => this._hideCard(), auto ? 9000 : 4500);
|
|
8271
|
+
resetIdleTimer(true);
|
|
8272
|
+
}
|
|
8273
|
+
};
|
|
8274
|
+
setInterval(() => { try { AUTO_CINEMA.tick(); } catch (_) { } }, 1200);
|
|
8275
|
+
|
|
8276
|
+
// ───────────────────────── Next episode
|
|
8277
|
+
// On series pages (drama/anime sites) the page usually has a "next episode" link or
|
|
8278
|
+
// button. Near the end of an episode in cinema mode a small card offers it, and when the
|
|
8279
|
+
// episode ends it counts down and moves on (in a room: everyone is invited along, and
|
|
8280
|
+
// this device comes back into the same room on the next page).
|
|
8281
|
+
const NEXT_EP = {
|
|
8282
|
+
_card: null,
|
|
8283
|
+
_target: null,
|
|
8284
|
+
_scanAt: 0,
|
|
8285
|
+
_cancelledFor: '',
|
|
8286
|
+
_count: null,
|
|
8287
|
+
enabled() { return STORE.get('nxu_auto_next', true) !== false; },
|
|
8288
|
+
RX_TEXT: /(다음\s*(화|회|편|회차|에피소드|episode|ep\.?)|다음\s*$|^\s*다음|next\s*(episode|ep\b|ep\.|part|chapter|video)|^\s*next\s*$|次の(話|エピソード)|次へ|下一[集话話]|siguiente\s*episodio|épisode\s*suivant|nächste\s*folge|próximo\s*episódio|⏭|»\s*$)/i,
|
|
8289
|
+
RX_ATTR: /(next[-_ ]?(ep|episode|video|btn|button|link)|btn[-_]?next|episode[-_]?next|nav[-_]?next|\bnext\b)/i,
|
|
8290
|
+
RX_BAD: /(prev|이전|previous|前|上一|comment|댓글|page|페이지|article|post|기사|뉴스)/i,
|
|
8291
|
+
_visible(el) {
|
|
8292
|
+
if (!el.isConnected || el.closest('#nxu-host')) return false;
|
|
8293
|
+
const r = el.getBoundingClientRect();
|
|
8294
|
+
if (r.width < 6 || r.height < 6) return false;
|
|
8295
|
+
const cs = getComputedStyle(el);
|
|
8296
|
+
return cs.visibility !== 'hidden' && cs.display !== 'none' && +cs.opacity > 0.05;
|
|
8297
|
+
},
|
|
8298
|
+
_label(el) {
|
|
8299
|
+
return [el.textContent, el.getAttribute('aria-label'), el.getAttribute('title'), el.getAttribute('alt')].filter(Boolean).join(' ').replace(/\s+/g, ' ').trim().slice(0, 80);
|
|
8300
|
+
},
|
|
8301
|
+
// → { el, href, label } or null
|
|
8302
|
+
find() {
|
|
8303
|
+
const here = location.origin + location.pathname + location.search;
|
|
8304
|
+
const out = [];
|
|
8305
|
+
const rel = document.querySelector('a[rel~="next"][href], link[rel~="next"][href]');
|
|
8306
|
+
if (rel) out.push({ el: rel.tagName === 'A' ? rel : null, href: rel.href, label: rel.tagName === 'A' ? this._label(rel) : '', score: 40 });
|
|
8307
|
+
const nodes = document.querySelectorAll('a[href], button, [role="button"], [onclick]');
|
|
8308
|
+
let n = 0;
|
|
8309
|
+
for (const el of nodes) {
|
|
8310
|
+
if (++n > 4000) break;
|
|
8311
|
+
const label = this._label(el);
|
|
8312
|
+
const attrs = `${el.id} ${typeof el.className === 'string' ? el.className : ''} ${el.getAttribute('data-action') || ''}`;
|
|
8313
|
+
let score = 0;
|
|
8314
|
+
if (this.RX_TEXT.test(label)) score += 60;
|
|
8315
|
+
if (this.RX_ATTR.test(attrs)) score += 25;
|
|
8316
|
+
if (!score) continue;
|
|
8317
|
+
if (this.RX_BAD.test(label) || /prev/i.test(attrs)) score -= 70;
|
|
8318
|
+
if (score <= 0 || !this._visible(el)) continue;
|
|
8319
|
+
const href = el.tagName === 'A' ? el.href : '';
|
|
8320
|
+
if (href) {
|
|
8321
|
+
if (/^javascript:/i.test(el.getAttribute('href') || '') || href.split('#')[0] === here) { if (!el.onclick && !el.hasAttribute('onclick')) continue; }
|
|
8322
|
+
else if (new URL(href).origin === location.origin) score += 10;
|
|
8323
|
+
}
|
|
8324
|
+
if (label.length > 60) score -= 15;
|
|
8325
|
+
out.push({ el, href, label, score });
|
|
8326
|
+
}
|
|
8327
|
+
out.sort((a, b) => b.score - a.score);
|
|
8328
|
+
const best = out[0];
|
|
8329
|
+
return best && best.score >= 40 ? best : null;
|
|
8330
|
+
},
|
|
8331
|
+
go(target = this._target) {
|
|
8332
|
+
if (!target) return;
|
|
8333
|
+
this.hide();
|
|
8334
|
+
showToast('⏭ ' + t('nextEpGoing'));
|
|
8335
|
+
const href = target.href && !/^javascript:/i.test(target.href) ? target.href : '';
|
|
8336
|
+
if (href && href.split('#')[0] !== location.href.split('#')[0]) {
|
|
8337
|
+
if (SOCIAL.live()) { TRAVEL.go(href); return; }
|
|
8338
|
+
location.href = href;
|
|
8339
|
+
return;
|
|
8340
|
+
}
|
|
8341
|
+
// A button that changes the episode with script: remember the room, then press it.
|
|
8342
|
+
try { TRAVEL.onLeavePage(); } catch (_) { }
|
|
8343
|
+
try { target.el?.click(); } catch (_) { }
|
|
8344
|
+
},
|
|
8345
|
+
hide() {
|
|
8346
|
+
clearInterval(this._count);
|
|
8347
|
+
this._count = null;
|
|
8348
|
+
const c = this._card;
|
|
8349
|
+
this._card = null;
|
|
8350
|
+
if (c) { c.classList.remove('in'); setTimeout(() => c.remove(), 260); }
|
|
8351
|
+
},
|
|
8352
|
+
_show(target, ended) {
|
|
8353
|
+
const container = getContainer();
|
|
8354
|
+
if (!container) return;
|
|
8355
|
+
if (!this._card || !this._card.isConnected) {
|
|
8356
|
+
const card = createEl('div', 'nx-next');
|
|
8357
|
+
const play = createEl('button', 'nx-next-go', '', { type: 'button' });
|
|
8358
|
+
play.append(createEl('span', 'nx-next-ring'), createEl('span', 'nx-next-ic', '⏭'));
|
|
8359
|
+
const text = createEl('div', 'nx-next-text');
|
|
8360
|
+
text.append(createEl('div', 'nx-next-k', t('nextEpTitle')), createEl('div', 'nx-next-l'));
|
|
8361
|
+
const cancel = createEl('button', 'nx-next-x', '✕', { type: 'button', title: t('nextEpCancel'), 'aria-label': t('nextEpCancel') });
|
|
8362
|
+
card.append(play, text, cancel);
|
|
8363
|
+
['pointerdown', 'click', 'touchstart'].forEach(ev => card.addEventListener(ev, (e) => e.stopPropagation()));
|
|
8364
|
+
play.onclick = () => this.go();
|
|
8365
|
+
text.onclick = () => this.go();
|
|
8366
|
+
cancel.onclick = () => { this._cancelledFor = location.href; this.hide(); UI_GUARD.shield(); };
|
|
8367
|
+
container.appendChild(card);
|
|
8368
|
+
this._card = card;
|
|
8369
|
+
requestAnimationFrame(() => card.classList.add('in'));
|
|
8370
|
+
}
|
|
8371
|
+
this._card.querySelector('.nx-next-l').textContent = target.label && target.label.length > 2 ? target.label : t('nextEpGo');
|
|
8372
|
+
if (ended && !this._count && this.enabled()) {
|
|
8373
|
+
let left = 8;
|
|
8374
|
+
const ring = this._card.querySelector('.nx-next-ring');
|
|
8375
|
+
this._card.classList.add('counting');
|
|
8376
|
+
ring.style.setProperty('--p', '0');
|
|
8377
|
+
ring.dataset.n = String(left);
|
|
8378
|
+
this._count = setInterval(() => {
|
|
8379
|
+
left--;
|
|
8380
|
+
ring.dataset.n = String(Math.max(0, left));
|
|
8381
|
+
ring.style.setProperty('--p', String((8 - left) / 8));
|
|
8382
|
+
if (left <= 0) { clearInterval(this._count); this._count = null; this.go(); }
|
|
8383
|
+
}, 1000);
|
|
8384
|
+
}
|
|
8385
|
+
},
|
|
8386
|
+
tick() {
|
|
8387
|
+
if (!IS_TOP || !STATE.isCinema) { if (this._card) this.hide(); return; }
|
|
8388
|
+
const info = currentMediaInfo();
|
|
8389
|
+
if (!info || !Number.isFinite(info.duration) || info.duration < 240) { if (this._card) this.hide(); return; }
|
|
8390
|
+
const left = info.duration - info.time;
|
|
8391
|
+
const ended = left <= 0.8 || (info.kind === 'video' && info.el.ended);
|
|
8392
|
+
if (left > 25 && !ended) { if (this._card) this.hide(); this._target = null; return; }
|
|
8393
|
+
if (this._cancelledFor === location.href) return;
|
|
8394
|
+
if (!this._target || Date.now() - this._scanAt > 5000) { this._scanAt = Date.now(); this._target = this.find(); }
|
|
8395
|
+
if (!this._target) return;
|
|
8396
|
+
this._show(this._target, ended);
|
|
8397
|
+
}
|
|
8398
|
+
};
|
|
8399
|
+
setInterval(() => { try { NEXT_EP.tick(); } catch (_) { } }, 1000);
|
|
8400
|
+
|
|
8029
8401
|
// ───────────────────────── Cover: hide the picture for a moment (for everyone)
|
|
8030
8402
|
// 🙈 (or H in cinema, Alt+Shift+H anywhere) lays a soft, nearly opaque curtain over the
|
|
8031
8403
|
// picture on every device in the room — for a violent or scary scene when children are
|
|
@@ -8670,7 +9042,7 @@
|
|
|
8670
9042
|
// Animations run on the compositor (Web Animations), with a hard cap on live nodes.
|
|
8671
9043
|
// Button feedback in the reaction bar: a springy pop, a ring and a few tiny copies of the
|
|
8672
9044
|
// emoji bursting out around the button (kept inside the bar's neighbourhood).
|
|
8673
|
-
const PRESS_COLORS = { '
|
|
9045
|
+
const PRESS_COLORS = { '😂': '#ffd54f', '😭': '#82b1ff', '😡': '#ff5252', '💦': '#4fc3f7', '🍪': '#d7a86e', '☕': '#bcaaa4', '😘': '#ff6fae', '🖕': '#ffb74d' };
|
|
8674
9046
|
function pressFx(btn, emoji) {
|
|
8675
9047
|
if (!btn) return;
|
|
8676
9048
|
btn.style.setProperty('--pop', PRESS_COLORS[emoji] || '#69f0ae');
|
|
@@ -8706,9 +9078,10 @@
|
|
|
8706
9078
|
_combo: new Map(), // lane → { n, timer, badge }
|
|
8707
9079
|
_tags: new Map(), // uid → last name-tag time
|
|
8708
9080
|
reduced() { try { return matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (_) { return false; } },
|
|
8709
|
-
_node(cls, text, x, y, size) {
|
|
9081
|
+
_node(cls, text, x, y, size, force = false) {
|
|
8710
9082
|
const container = getContainer();
|
|
8711
|
-
|
|
9083
|
+
// The burst's ring and glow always get a place, even when many small bits are flying.
|
|
9084
|
+
if (!container || (this.live >= this.MAX && !force)) return null;
|
|
8712
9085
|
const el = createEl('div', 'rx ' + cls, text);
|
|
8713
9086
|
el.style.left = x + 'px';
|
|
8714
9087
|
el.style.top = y + 'px';
|
|
@@ -8763,7 +9136,7 @@
|
|
|
8763
9136
|
const sway = (Math.random() < 0.5 ? -1 : 1) * (10 + Math.random() * 14);
|
|
8764
9137
|
const d = 1700 + Math.random() * 500;
|
|
8765
9138
|
const base = { duration: d, delay };
|
|
8766
|
-
const kind = { '❤️': 'heart', '💗': 'heart', '😂': 'laugh', '😭': 'cry', '😡': 'angry', '🫣': 'peek', '🌰': 'toss', '🚽': 'flush' }[e] || 'float';
|
|
9139
|
+
const kind = { '❤️': 'heart', '💗': 'heart', '😂': 'laugh', '😭': 'cry', '😡': 'angry', '💦': 'splash', '🍪': 'munch', '☕': 'steam', '😘': 'kiss', '🖕': 'flip', '🫣': 'peek', '🌰': 'toss', '🚽': 'flush' }[e] || 'float';
|
|
8767
9140
|
if (this.reduced()) { this._run(el, [{ opacity: 0 }, { opacity: 1, offset: 0.2 }, { opacity: 0, transform: `translateY(${-R * 0.4}px)` }], base); return; }
|
|
8768
9141
|
switch (kind) {
|
|
8769
9142
|
case 'heart':
|
|
@@ -8813,6 +9186,101 @@
|
|
|
8813
9186
|
{ const puff = this._node('rx-mini', '💢', x + size * 0.7, lane.y - R * 0.3, 16);
|
|
8814
9187
|
this._run(puff, [{ transform: 'scale(0.3)', opacity: 0 }, { transform: 'scale(1.3)', opacity: 1, offset: 0.4 }, { transform: 'translateY(-30px) scale(0.6)', opacity: 0 }], { duration: 800, delay: delay + 300 }); }
|
|
8815
9188
|
break;
|
|
9189
|
+
case 'splash': {
|
|
9190
|
+
// Shoots up with a little shiver, then bursts into droplets.
|
|
9191
|
+
this._run(el, [
|
|
9192
|
+
{ transform: 'translate(0,0) scale(0.3) rotate(0)', opacity: 0 },
|
|
9193
|
+
{ transform: `translate(0, ${-R * 0.42}px) scale(1.25) rotate(-6deg)`, opacity: 1, offset: 0.3 },
|
|
9194
|
+
{ transform: `translate(3px, ${-R * 0.46}px) scale(1.15) rotate(6deg)`, offset: 0.38 },
|
|
9195
|
+
{ transform: `translate(-3px, ${-R * 0.5}px) scale(1.2) rotate(-4deg)`, offset: 0.46 },
|
|
9196
|
+
{ transform: `translate(0, ${-R * 0.55}px) scale(1.5)`, opacity: 0, offset: 0.6 },
|
|
9197
|
+
{ transform: `translate(0, ${-R * 0.55}px) scale(1.5)`, opacity: 0 }
|
|
9198
|
+
], { ...base, duration: 1500 });
|
|
9199
|
+
for (let i = 0; i < 6; i++) {
|
|
9200
|
+
const ang = -Math.PI / 2 + (i - 2.5) * 0.42;
|
|
9201
|
+
const dist = 40 + Math.random() * 34;
|
|
9202
|
+
const drop = this._node('rx-mini', '💧', x + size * 0.35, lane.y - R * 0.55, 13 + Math.random() * 5);
|
|
9203
|
+
this._run(drop, [
|
|
9204
|
+
{ transform: 'translate(0,0) scale(0.4)', opacity: 0 },
|
|
9205
|
+
{ transform: `translate(${Math.cos(ang) * dist}px, ${Math.sin(ang) * dist}px) scale(1)`, opacity: 1, offset: 0.4 },
|
|
9206
|
+
{ transform: `translate(${Math.cos(ang) * dist * 1.3}px, ${Math.sin(ang) * dist + 70}px) scale(0.7)`, opacity: 0 }
|
|
9207
|
+
], { duration: 900, delay: delay + 850, easing: 'cubic-bezier(.2,.6,.6,1)' });
|
|
9208
|
+
}
|
|
9209
|
+
break;
|
|
9210
|
+
}
|
|
9211
|
+
case 'munch': {
|
|
9212
|
+
// Rises, gets two quick bites (squash), crumbs fall.
|
|
9213
|
+
this._run(el, [
|
|
9214
|
+
{ transform: 'translate(0,0) scale(0.4) rotate(-20deg)', opacity: 0 },
|
|
9215
|
+
{ transform: `translate(${sway * 0.4}px, ${-R * 0.4}px) scale(1.15) rotate(8deg)`, opacity: 1, offset: 0.28 },
|
|
9216
|
+
{ transform: `translate(${sway * 0.4}px, ${-R * 0.44}px) scale(1.25, 0.85) rotate(0)`, offset: 0.36 },
|
|
9217
|
+
{ transform: `translate(${sway * 0.4}px, ${-R * 0.47}px) scale(1.1) rotate(-4deg)`, offset: 0.44 },
|
|
9218
|
+
{ transform: `translate(${sway * 0.4}px, ${-R * 0.5}px) scale(1.25, 0.85)`, offset: 0.52 },
|
|
9219
|
+
{ transform: `translate(${-sway * 0.3}px, ${-R * 0.85}px) scale(0.9) rotate(10deg)`, opacity: 0 }
|
|
9220
|
+
], base);
|
|
9221
|
+
for (let i = 0; i < 5; i++) {
|
|
9222
|
+
const crumb = this._node('rx-crumb', '', x + size * (0.25 + Math.random() * 0.5), lane.y - R * 0.45, 0);
|
|
9223
|
+
this._run(crumb, [
|
|
9224
|
+
{ transform: 'translate(0,0) scale(0.6)', opacity: 0 },
|
|
9225
|
+
{ transform: `translate(${(Math.random() - 0.5) * 30}px, 8px) scale(1)`, opacity: 1, offset: 0.2 },
|
|
9226
|
+
{ transform: `translate(${(Math.random() - 0.5) * 50}px, ${50 + Math.random() * 40}px) rotate(${Math.random() * 180}deg)`, opacity: 0 }
|
|
9227
|
+
], { duration: 800, delay: delay + d * 0.34 + i * 60, easing: 'ease-in' });
|
|
9228
|
+
}
|
|
9229
|
+
break;
|
|
9230
|
+
}
|
|
9231
|
+
case 'steam': {
|
|
9232
|
+
// A calm cup: slow rise, gentle sway, steam curling up.
|
|
9233
|
+
this._run(el, [
|
|
9234
|
+
{ transform: 'translate(0,0) scale(0.6)', opacity: 0 },
|
|
9235
|
+
{ transform: `translate(${sway * 0.3}px, ${-R * 0.25}px) scale(1.05)`, opacity: 1, offset: 0.25 },
|
|
9236
|
+
{ transform: `translate(${-sway * 0.3}px, ${-R * 0.45}px) scale(1.05)`, offset: 0.55 },
|
|
9237
|
+
{ transform: `translate(${sway * 0.2}px, ${-R * 0.6}px) scale(0.95)`, opacity: 0 }
|
|
9238
|
+
], { ...base, duration: 2400, easing: 'ease-in-out' });
|
|
9239
|
+
for (let i = 0; i < 3; i++) {
|
|
9240
|
+
const wisp = this._node('rx-steam', '', x + size * (0.3 + i * 0.18), lane.y - R * 0.3 - size * 0.6, 0);
|
|
9241
|
+
this._run(wisp, [
|
|
9242
|
+
{ transform: 'translate(0,0) scale(0.6, 0.8)', opacity: 0 },
|
|
9243
|
+
{ transform: `translate(${i % 2 ? 6 : -6}px, -22px) scale(1, 1.2)`, opacity: 0.8, offset: 0.4 },
|
|
9244
|
+
{ transform: `translate(${i % 2 ? -4 : 4}px, -52px) scale(1.4, 1.6)`, opacity: 0 }
|
|
9245
|
+
], { duration: 1500, delay: delay + 500 + i * 220, easing: 'ease-out' });
|
|
9246
|
+
}
|
|
9247
|
+
break;
|
|
9248
|
+
}
|
|
9249
|
+
case 'kiss': {
|
|
9250
|
+
// Leans in, then blows a kiss that floats toward the middle of the screen.
|
|
9251
|
+
const toward = lane.x > lane.W / 2 ? -1 : 1;
|
|
9252
|
+
this._run(el, [
|
|
9253
|
+
{ transform: 'translate(0,0) scale(0.4) rotate(0)', opacity: 0 },
|
|
9254
|
+
{ transform: `translate(0, ${-R * 0.35}px) scale(1.2) rotate(${toward * 12}deg)`, opacity: 1, offset: 0.3 },
|
|
9255
|
+
{ transform: `translate(${toward * 6}px, ${-R * 0.38}px) scale(1.05, 1.15) rotate(${toward * 18}deg)`, offset: 0.45 },
|
|
9256
|
+
{ transform: `translate(0, ${-R * 0.55}px) scale(0.9) rotate(0)`, opacity: 0 }
|
|
9257
|
+
], base);
|
|
9258
|
+
for (let i = 0; i < 2; i++) {
|
|
9259
|
+
const heart = this._node('rx-mini', i ? '💗' : '💋', x + size * 0.5, lane.y - R * 0.38, i ? 15 : 18);
|
|
9260
|
+
this._run(heart, [
|
|
9261
|
+
{ transform: 'translate(0,0) scale(0.3)', opacity: 0 },
|
|
9262
|
+
{ transform: `translate(${toward * 40}px, -16px) scale(1.15)`, opacity: 1, offset: 0.3 },
|
|
9263
|
+
{ transform: `translate(${toward * 110}px, -40px) scale(1)`, offset: 0.7 },
|
|
9264
|
+
{ transform: `translate(${toward * 150}px, -60px) scale(0.6)`, opacity: 0 }
|
|
9265
|
+
], { duration: 1300, delay: delay + d * 0.42 + i * 180, easing: 'ease-out' });
|
|
9266
|
+
}
|
|
9267
|
+
break;
|
|
9268
|
+
}
|
|
9269
|
+
case 'flip':
|
|
9270
|
+
// Cheeky: pops up, two jabs toward the screen, a shake, gone.
|
|
9271
|
+
this._run(el, [
|
|
9272
|
+
{ transform: 'translate(0,0) scale(0.3)', opacity: 0 },
|
|
9273
|
+
{ transform: `translate(0, ${-R * 0.3}px) scale(1.1)`, opacity: 1, offset: 0.18 },
|
|
9274
|
+
{ transform: `translate(0, ${-R * 0.33}px) scale(1.45)`, offset: 0.26 },
|
|
9275
|
+
{ transform: `translate(0, ${-R * 0.34}px) scale(1.1)`, offset: 0.33 },
|
|
9276
|
+
{ transform: `translate(0, ${-R * 0.36}px) scale(1.45)`, offset: 0.41 },
|
|
9277
|
+
{ transform: `translate(-4px, ${-R * 0.38}px) scale(1.15) rotate(-8deg)`, offset: 0.5 },
|
|
9278
|
+
{ transform: `translate(4px, ${-R * 0.4}px) scale(1.15) rotate(8deg)`, offset: 0.57 },
|
|
9279
|
+
{ transform: `translate(0, ${-R * 0.7}px) scale(0.9)`, opacity: 0 }
|
|
9280
|
+
], { ...base, easing: 'ease-out' });
|
|
9281
|
+
{ const pop = this._node('rx-mini', '💥', x + size * 0.6, lane.y - R * 0.36, 16);
|
|
9282
|
+
this._run(pop, [{ transform: 'scale(0.2)', opacity: 0 }, { transform: 'scale(1.3)', opacity: 1, offset: 0.35 }, { transform: 'scale(0.6) translateY(-16px)', opacity: 0 }], { duration: 600, delay: delay + d * 0.25 }); }
|
|
9283
|
+
break;
|
|
8816
9284
|
case 'peek':
|
|
8817
9285
|
this._run(el, [
|
|
8818
9286
|
{ transform: `translate(${lane.x > lane.W / 2 ? 60 : -60}px, ${-R * 0.3}px) scale(1)`, opacity: 0 },
|
|
@@ -8874,12 +9342,12 @@
|
|
|
8874
9342
|
_burst(e, side, color) {
|
|
8875
9343
|
const lane = this._lane(side);
|
|
8876
9344
|
const ox = side === 'right' ? lane.W - 30 : 30, oy = lane.y + 20;
|
|
8877
|
-
const ring = this._node('rx-ring', '', ox, oy);
|
|
9345
|
+
const ring = this._node('rx-ring', '', ox, oy, 0, true);
|
|
8878
9346
|
if (ring) {
|
|
8879
9347
|
ring.style.setProperty('--c', color);
|
|
8880
9348
|
this._run(ring, [{ transform: 'translate(-50%,-50%) scale(0.2)', opacity: 0.9 }, { transform: 'translate(-50%,-50%) scale(4.2)', opacity: 0 }], { duration: 900, easing: 'ease-out' });
|
|
8881
9349
|
}
|
|
8882
|
-
const glow = this._node('rx-glow ' + side, '', 0, 0);
|
|
9350
|
+
const glow = this._node('rx-glow ' + side, '', 0, 0, 0, true);
|
|
8883
9351
|
if (glow) {
|
|
8884
9352
|
glow.style.setProperty('--c', color);
|
|
8885
9353
|
this._run(glow, [{ opacity: 0 }, { opacity: 1, offset: 0.25 }, { opacity: 0 }], { duration: 1100 });
|
|
@@ -9139,7 +9607,7 @@
|
|
|
9139
9607
|
_scrubbing: false,
|
|
9140
9608
|
_wasPaused: null,
|
|
9141
9609
|
|
|
9142
|
-
controlsMode() { return
|
|
9610
|
+
controlsMode() { return cinemaControlsMode(); },
|
|
9143
9611
|
|
|
9144
9612
|
_setIcon(el, name, size = 22, label = '') {
|
|
9145
9613
|
const key = `${name}|${size}|${label}`;
|
|
@@ -9216,7 +9684,7 @@
|
|
|
9216
9684
|
const subBtn = btn('cc-sub', 'cc', t('aiSubTitle'));
|
|
9217
9685
|
const fitBtn = btn('cc-fit', 'fit', t('ccFit'));
|
|
9218
9686
|
const ambientBtn = btn('cc-ambient', 'ambient', t('ccAmbient'));
|
|
9219
|
-
const pipBtn = btn('cc-pip', 'pip', '
|
|
9687
|
+
const pipBtn = btn('cc-pip', 'pip', t('ccPip'));
|
|
9220
9688
|
const fsBtn = btn('cc-fs', 'fullscreen', t('ccFullscreen'));
|
|
9221
9689
|
row.append(playBtn, backBtn, fwdBtn, vol, time, live, spacer, rateBtn, subBtn, fitBtn, ambientBtn, pipBtn, fsBtn);
|
|
9222
9690
|
bottom.append(seek, row);
|
|
@@ -10528,6 +10996,7 @@
|
|
|
10528
10996
|
if (uiElements.btnRate) uiElements.btnRate.style.display = hasMedia ? '' : 'none';
|
|
10529
10997
|
updateRateButton();
|
|
10530
10998
|
if (uiElements.btnCinema) uiElements.btnCinema.style.display = hasMedia || STATE.isCinema ? '' : 'none';
|
|
10999
|
+
if (uiElements.btnAutoCinema) { uiElements.btnAutoCinema.style.display = hasMedia || STATE.isCinema ? '' : 'none'; AUTO_CINEMA.paintButton(); }
|
|
10531
11000
|
if (uiElements.btnBookmark) uiElements.btnBookmark.style.display = hasMedia ? '' : 'none';
|
|
10532
11001
|
if (uiElements.btnFindMedia) uiElements.btnFindMedia.style.display = hasMedia ? 'none' : '';
|
|
10533
11002
|
if (uiElements.btnLink) uiElements.btnLink.style.display = hasMedia || connected ? '' : 'none';
|
|
@@ -10578,7 +11047,7 @@
|
|
|
10578
11047
|
initFirebaseStreaming(STATE.handshakeVerified ? 'nexus_rooms' : (NETWORK.streamNode || 'nexus_rooms'),
|
|
10579
11048
|
STATE.handshakeVerified ? STATE.topicId : (NETWORK.streamNode === 'nexus_lobbies' ? STATE.lobbyId : STATE.topicId));
|
|
10580
11049
|
if (STATE.handshakeVerified) {
|
|
10581
|
-
try { if (ydoc && yPresence) ydoc.transact(() => yPresence.set(STATE.userId, { ts: Date.now(), color: STATE.color, viewer: !!STATE.isViewer, nick: STATE.nickname || '', v: NXU_VERSION, r: NXU_RANK }), 'local'); } catch (_) { }
|
|
11050
|
+
try { if (ydoc && yPresence) ydoc.transact(() => yPresence.set(STATE.userId, { ts: Date.now(), color: STATE.color, viewer: !!STATE.isViewer, nick: STATE.nickname || '', v: NXU_VERSION, r: NXU_RANK, sess: NXU_SESSION, hid: !!document.hidden }), 'local'); } catch (_) { }
|
|
10582
11051
|
sendFirebaseCmd('heartbeat', { ts: Date.now() }, 'nexus_rooms');
|
|
10583
11052
|
syncServerClock();
|
|
10584
11053
|
if (RTC.isHost && STATE.connectionMode === 'HTTP_RELAY') RTC.init();
|
|
@@ -10587,6 +11056,8 @@
|
|
|
10587
11056
|
window.addEventListener('pageshow', (e) => { if (e.persisted) { DEVICE_GUARD.onVisible(60000); reviveConnection('page restore'); } });
|
|
10588
11057
|
window.addEventListener('pagehide', () => DEVICE_GUARD.onHidden());
|
|
10589
11058
|
document.addEventListener('visibilitychange', () => {
|
|
11059
|
+
// Tell the room at once whether this device is in the foreground (leadership).
|
|
11060
|
+
if (IS_TOP) try { PROFILE.publish(); } catch (_) { }
|
|
10590
11061
|
if (document.hidden) { _hiddenSince = Date.now(); DEVICE_GUARD.onHidden(); return; }
|
|
10591
11062
|
const away = _hiddenSince ? Date.now() - _hiddenSince : 0;
|
|
10592
11063
|
_hiddenSince = 0;
|
|
@@ -10824,6 +11295,18 @@
|
|
|
10824
11295
|
console.info('[NexusSync] v' + NXU_VERSION + ' handed over to a newer version on this page.');
|
|
10825
11296
|
});
|
|
10826
11297
|
|
|
11298
|
+
// ───────────────────────── Bundled sync engine
|
|
11299
|
+
// Yjs 13.6.14 with lib0 — MIT License, © Kevin Jahns (https://github.com/yjs/yjs).
|
|
11300
|
+
// Built with esbuild (--format=iife --minify); see scripts in the repository.
|
|
11301
|
+
function nxuLoadYjs() {
|
|
11302
|
+
var Y=(()=>{var Je=Object.defineProperty;var Zi=Object.getOwnPropertyDescriptor;var Qi=Object.getOwnPropertyNames;var to=Object.prototype.hasOwnProperty;var eo=(e,t,n)=>t in e?Je(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var no=(e,t)=>{for(var n in t)Je(e,n,{get:t[n],enumerable:!0})},ro=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Qi(t))!to.call(e,s)&&s!==n&&Je(e,s,{get:()=>t[s],enumerable:!(r=Zi(t,s))||r.enumerable});return e};var so=e=>ro(Je({},"__esModule",{value:!0}),e);var Xe=(e,t,n)=>eo(e,typeof t!="symbol"?t+"":t,n);var na={};no(na,{AbsolutePosition:()=>Tn,AbstractConnector:()=>Tr,AbstractStruct:()=>ae,AbstractType:()=>C,Array:()=>Vt,ContentAny:()=>yt,ContentBinary:()=>Bt,ContentDeleted:()=>he,ContentDoc:()=>Mt,ContentEmbed:()=>at,ContentFormat:()=>E,ContentJSON:()=>ze,ContentString:()=>Y,ContentType:()=>K,Doc:()=>Tt,GC:()=>N,ID:()=>ct,Item:()=>S,Map:()=>Ot,PermanentUserData:()=>vr,RelativePosition:()=>ce,Skip:()=>O,Snapshot:()=>Me,Text:()=>le,Transaction:()=>vn,UndoManager:()=>Lr,UpdateDecoderV1:()=>j,UpdateDecoderV2:()=>R,UpdateEncoderV1:()=>nt,UpdateEncoderV2:()=>J,XmlElement:()=>Lt,XmlFragment:()=>Nt,XmlHook:()=>Ge,XmlText:()=>Rn,YArrayEvent:()=>Nn,YEvent:()=>vt,YMapEvent:()=>Ln,YTextEvent:()=>Bn,YXmlEvent:()=>Mn,applyUpdate:()=>Lc,applyUpdateV2:()=>jn,cleanupYTextFormatting:()=>Ji,compareIDs:()=>At,compareRelativePositions:()=>Wc,convertUpdateFormatV1ToV2:()=>yl,convertUpdateFormatV2ToV1:()=>Ti,createAbsolutePositionFromRelativePosition:()=>Yc,createDeleteSet:()=>Fn,createDeleteSetFromStructStore:()=>Fr,createDocFromSnapshot:()=>rl,createID:()=>w,createRelativePositionFromJSON:()=>Gc,createRelativePositionFromTypeIndex:()=>Hc,createSnapshot:()=>Jr,decodeRelativePosition:()=>Kc,decodeSnapshot:()=>tl,decodeSnapshotV2:()=>mi,decodeStateVector:()=>Gr,decodeUpdate:()=>ul,decodeUpdateV2:()=>_i,diffUpdate:()=>gl,diffUpdateV2:()=>Xr,emptySnapshot:()=>el,encodeRelativePosition:()=>Xc,encodeSnapshot:()=>Qc,encodeSnapshotV2:()=>gi,encodeStateAsUpdate:()=>Mc,encodeStateAsUpdateV2:()=>di,encodeStateVector:()=>Fc,encodeStateVectorFromUpdate:()=>dl,encodeStateVectorFromUpdateV2:()=>Ui,equalDeleteSets:()=>hi,equalSnapshots:()=>Zc,findIndexSS:()=>P,findRootTypeKey:()=>Hr,getItem:()=>Ve,getState:()=>_,getTypeChildren:()=>Sl,isDeleted:()=>Rt,isParentOf:()=>Be,iterateDeletedStructs:()=>It,logType:()=>jc,logUpdate:()=>hl,logUpdateV2:()=>Si,mergeUpdates:()=>Ei,mergeUpdatesV2:()=>$e,obfuscateUpdate:()=>ml,obfuscateUpdateV2:()=>wl,parseUpdateMeta:()=>fl,parseUpdateMetaV2:()=>Ci,readUpdate:()=>Nc,readUpdateV2:()=>qr,relativePositionToJSON:()=>qc,snapshot:()=>nl,snapshotContainsUpdate:()=>il,transact:()=>k,tryGc:()=>ll,typeListToArraySnapshot:()=>_l,typeMapGetAllSnapshot:()=>ji,typeMapGetSnapshot:()=>Cl});var A=()=>new Map,Pe=e=>{let t=A();return e.forEach((n,r)=>{t.set(r,n)}),t},L=(e,t,n)=>{let r=e.get(t);return r===void 0&&e.set(t,r=n()),r},ts=(e,t)=>{let n=[];for(let[r,s]of e)n.push(t(s,r));return n},es=(e,t)=>{for(let[n,r]of e)if(t(r,n))return!0;return!1};var st=()=>new Set;var Ke=e=>e[e.length-1];var ns=(e,t)=>{for(let n=0;n<t.length;n++)e.push(t[n])},W=Array.from,Ye=(e,t)=>{for(let n=0;n<e.length;n++)if(!t(e[n],n,e))return!1;return!0},fe=(e,t)=>{for(let n=0;n<e.length;n++)if(t(e[n],n,e))return!0;return!1};var rs=(e,t)=>{let n=new Array(e);for(let r=0;r<e;r++)n[r]=t(r,n);return n};var it=Array.isArray;var $t=class{constructor(){this._observers=A()}on(t,n){return L(this._observers,t,st).add(n),n}once(t,n){let r=(...s)=>{this.off(t,r),n(...s)};this.on(t,r)}off(t,n){let r=this._observers.get(t);r!==void 0&&(r.delete(n),r.size===0&&this._observers.delete(t))}emit(t,n){return W((this._observers.get(t)||A()).values()).forEach(r=>r(...n))}destroy(){this._observers=A()}};var B=Math.floor;var xt=Math.abs;var We=(e,t)=>e<t?e:t,ot=(e,t)=>e>t?e:t,ia=Number.isNaN;var Ze=e=>e!==0?e<0:1/e<0;var Ft=Number.MAX_SAFE_INTEGER,Jn=Number.MIN_SAFE_INTEGER,oa=1<<31;var ss=Number.isInteger||(e=>typeof e=="number"&&isFinite(e)&&B(e)===e),ca=Number.isNaN,la=Number.parseInt;var Pn=String.fromCharCode,io=String.fromCodePoint,aa=Pn(65535),oo=e=>e.toLowerCase(),co=/^\s*/g,lo=e=>e.replace(co,""),ao=/([A-Z])/g,Kn=(e,t)=>lo(e.replace(ao,n=>`${t}${oo(n)}`));var ho=e=>{let t=unescape(encodeURIComponent(e)),n=t.length,r=new Uint8Array(n);for(let s=0;s<n;s++)r[s]=t.codePointAt(s);return r},qt=typeof TextEncoder!="undefined"?new TextEncoder:null,uo=e=>qt.encode(e),is=qt?uo:ho;var jt=typeof TextDecoder=="undefined"?null:new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});jt&&jt.decode(new Uint8Array).length===1&&(jt=null);var Qe=(e,t)=>rs(t,()=>e).join("");var bt=class{constructor(){this.cpos=0,this.cbuf=new Uint8Array(100),this.bufs=[]}},St=()=>new bt;var fo=e=>{let t=e.cpos;for(let n=0;n<e.bufs.length;n++)t+=e.bufs[n].length;return t};var G=e=>{let t=new Uint8Array(fo(e)),n=0;for(let r=0;r<e.bufs.length;r++){let s=e.bufs[r];t.set(s,n),n+=s.length}return t.set(new Uint8Array(e.cbuf.buffer,0,e.cpos),n),t},po=(e,t)=>{let n=e.cbuf.length;n-e.cpos<t&&(e.bufs.push(new Uint8Array(e.cbuf.buffer,0,e.cpos)),e.cbuf=new Uint8Array(ot(n,t)*2),e.cpos=0)},T=(e,t)=>{let n=e.cbuf.length;e.cpos===n&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(n*2),e.cpos=0),e.cbuf[e.cpos++]=t};var Jt=T;var g=(e,t)=>{for(;t>127;)T(e,128|127&t),t=B(t/128);T(e,127&t)},ye=(e,t)=>{let n=Ze(t);for(n&&(t=-t),T(e,(t>63?128:0)|(n?64:0)|63&t),t=B(t/64);t>0;)T(e,(t>127?128:0)|127&t),t=B(t/128)},Yn=new Uint8Array(3e4),go=Yn.length/3,mo=(e,t)=>{if(t.length<go){let n=qt.encodeInto(t,Yn).written||0;g(e,n);for(let r=0;r<n;r++)T(e,Yn[r])}else $(e,is(t))},wo=(e,t)=>{let n=unescape(encodeURIComponent(t)),r=n.length;g(e,r);for(let s=0;s<r;s++)T(e,n.codePointAt(s))},ht=qt&&qt.encodeInto?mo:wo;var hs=(e,t)=>Xt(e,G(t)),Xt=(e,t)=>{let n=e.cbuf.length,r=e.cpos,s=We(n-r,t.length),i=t.length-s;e.cbuf.set(t.subarray(0,s),r),e.cpos+=s,i>0&&(e.bufs.push(e.cbuf),e.cbuf=new Uint8Array(ot(n*2,i)),e.cbuf.set(t.subarray(s)),e.cpos=i)},$=(e,t)=>{g(e,t.byteLength),Xt(e,t)},Wn=(e,t)=>{po(e,t);let n=new DataView(e.cbuf.buffer,e.cpos,t);return e.cpos+=t,n},yo=(e,t)=>Wn(e,4).setFloat32(0,t,!1),xo=(e,t)=>Wn(e,8).setFloat64(0,t,!1),bo=(e,t)=>Wn(e,8).setBigInt64(0,t,!1);var cs=new DataView(new ArrayBuffer(4)),ko=e=>(cs.setFloat32(0,e),cs.getFloat32(0)===e),zt=(e,t)=>{switch(typeof t){case"string":T(e,119),ht(e,t);break;case"number":ss(t)&&xt(t)<=2147483647?(T(e,125),ye(e,t)):ko(t)?(T(e,124),yo(e,t)):(T(e,123),xo(e,t));break;case"bigint":T(e,122),bo(e,t);break;case"object":if(t===null)T(e,126);else if(it(t)){T(e,117),g(e,t.length);for(let n=0;n<t.length;n++)zt(e,t[n])}else if(t instanceof Uint8Array)T(e,116),$(e,t);else{T(e,118);let n=Object.keys(t);g(e,n.length);for(let r=0;r<n.length;r++){let s=n[r];ht(e,s),zt(e,t[s])}}break;case"boolean":T(e,t?120:121);break;default:T(e,127)}},we=class extends bt{constructor(t){super(),this.w=t,this.s=null,this.count=0}write(t){this.s===t?this.count++:(this.count>0&&g(this,this.count-1),this.count=1,this.w(this,t),this.s=t)}};var ls=e=>{e.count>0&&(ye(e.encoder,e.count===1?e.s:-e.s),e.count>1&&g(e.encoder,e.count-2))},kt=class{constructor(){this.encoder=new bt,this.s=0,this.count=0}write(t){this.s===t?this.count++:(ls(this),this.count=1,this.s=t)}toUint8Array(){return ls(this),G(this.encoder)}};var as=e=>{if(e.count>0){let t=e.diff*2+(e.count===1?0:1);ye(e.encoder,t),e.count>1&&g(e.encoder,e.count-2)}},Ht=class{constructor(){this.encoder=new bt,this.s=0,this.count=0,this.diff=0}write(t){this.diff===t-this.s?(this.s=t,this.count++):(as(this),this.count=1,this.diff=t-this.s,this.s=t)}toUint8Array(){return as(this),G(this.encoder)}},tn=class{constructor(){this.sarr=[],this.s="",this.lensE=new kt}write(t){this.s+=t,this.s.length>19&&(this.sarr.push(this.s),this.s=""),this.lensE.write(t.length)}toUint8Array(){let t=new bt;return this.sarr.push(this.s),this.s="",ht(t,this.sarr.join("")),Xt(t,this.lensE.toUint8Array()),G(t)}};var z=e=>new Error(e),H=()=>{throw z("Method unimplemented")},D=()=>{throw z("Unexpected case")};var nn=z("Unexpected end of array"),us=z("Integer out of Range"),_o=(e,t,n)=>{if(t<0||n<0||t+n>e.length)throw nn;return new Uint8Array(e.buffer,e.byteOffset+t,n)},Eo=(e,t,n)=>{if(t<0||n<0||t+n>e.length)throw nn;return new DataView(e.buffer,e.byteOffset+t,n)},Pt=class{constructor(t){this.arr=t,this.pos=0}},V=e=>new Pt(e),Qn=e=>e.pos!==e.arr.length;var Uo=(e,t)=>{let n=_o(e.arr,e.pos,t);return e.pos+=t,n},F=e=>Uo(e,y(e));var _t=e=>e.arr[e.pos++];var y=e=>{let t=0,n=1,r=e.arr.length;for(;e.pos<r;){let s=e.arr[e.pos++];if(t=t+(s&127)*n,n*=128,s<128)return t;if(t>Ft)throw us}throw nn},be=e=>{let t=e.arr[e.pos++],n=t&63,r=64,s=(t&64)>0?-1:1;if(!(t&128))return s*n;let i=e.arr.length;for(;e.pos<i;){if(t=e.arr[e.pos++],n=n+(t&127)*r,r*=128,t<128)return s*n;if(n>Ft)throw us}throw nn};var Co=e=>{let t=y(e);if(t===0)return"";{let n=String.fromCodePoint(_t(e));if(--t<100)for(;t--;)n+=String.fromCodePoint(_t(e));else for(;t>0;){let r=t<1e4?t:1e4,s=e.arr.subarray(e.pos,e.pos+r);e.pos+=r,n+=String.fromCodePoint.apply(null,s),t-=r}return decodeURIComponent(escape(n))}},Ao=e=>jt.decode(F(e)),dt=jt?Ao:Co;var tr=(e,t)=>{let n=Eo(e.arr,e.pos,t);return e.pos+=t,n},Io=e=>tr(e,4).getFloat32(0,!1),To=e=>tr(e,8).getFloat64(0,!1),Do=e=>tr(e,8).getBigInt64(0,!1);var vo=[e=>{},e=>null,be,Io,To,Do,e=>!1,e=>!0,dt,e=>{let t=y(e),n={};for(let r=0;r<t;r++){let s=dt(e);n[s]=Kt(e)}return n},e=>{let t=y(e),n=[];for(let r=0;r<t;r++)n.push(Kt(e));return n},F],Kt=e=>vo[127-_t(e)](e),xe=class extends Pt{constructor(t,n){super(t),this.reader=n,this.s=null,this.count=0}read(){return this.count===0&&(this.s=this.reader(this),Qn(this)?this.count=y(this)+1:this.count=-1),this.count--,this.s}};var Et=class extends Pt{constructor(t){super(t),this.s=0,this.count=0}read(){if(this.count===0){this.s=be(this);let t=Ze(this.s);this.count=1,t&&(this.s=-this.s,this.count=y(this)+2)}return this.count--,this.s}};var Yt=class extends Pt{constructor(t){super(t),this.s=0,this.count=0,this.diff=0}read(){if(this.count===0){let t=be(this),n=t&1;this.diff=B(t/2),this.count=1,n&&(this.count=y(this)+2)}return this.s+=this.diff,this.count--,this.s}},en=class{constructor(t){this.decoder=new Et(t),this.str=dt(this.decoder),this.spos=0}read(){let t=this.spos+this.decoder.read(),n=this.str.slice(this.spos,t);return this.spos=t,n}};var da=crypto.subtle,ds=crypto.getRandomValues.bind(crypto);var er=()=>ds(new Uint32Array(1))[0];var Oo="10000000-1000-4000-8000"+-1e11,fs=()=>Oo.replace(/[018]/g,e=>(e^er()&15>>e/4).toString(16));var rn=Date.now;var nr=e=>new Promise(e);var ga=Promise.all.bind(Promise);var rr=e=>e===void 0?null:e;var sr=class{constructor(){this.map=new Map}setItem(t,n){this.map.set(t,n)}getItem(t){return this.map.get(t)}},gs=new sr,Mo=!0;try{typeof localStorage!="undefined"&&localStorage&&(gs=localStorage,Mo=!1)}catch{}var ms=gs;var Ut=Symbol("Equality"),sn=(e,t)=>{var n;return e===t||!!((n=e==null?void 0:e[Ut])!=null&&n.call(e,t))||!1};var ws=e=>typeof e=="object",ys=Object.assign,$o=Object.keys;var xs=(e,t)=>{for(let n in e)t(e[n],n)};var ke=e=>$o(e).length;var bs=e=>{for(let t in e)return!1;return!0},Wt=(e,t)=>{for(let n in e)if(!t(e[n],n))return!1;return!0},Se=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),or=(e,t)=>e===t||ke(e)===ke(t)&&Wt(e,(n,r)=>(n!==void 0||Se(t,r))&&sn(t[r],n));var Ee=(e,t,n=0)=>{try{for(;n<e.length;n++)e[n](...t)}finally{n<e.length&&Ee(e,t,n+1)}};var lr=e=>e;var _e=(e,t)=>{if(e===t)return!0;if(e==null||t==null||e.constructor!==t.constructor&&(e.constructor||Object)!==(t.constructor||Object))return!1;if(e[Ut]!=null)return e[Ut](t);switch(e.constructor){case ArrayBuffer:e=new Uint8Array(e),t=new Uint8Array(t);case Uint8Array:{if(e.byteLength!==t.byteLength)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;break}case Set:{if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;break}case Map:{if(e.size!==t.size)return!1;for(let n of e.keys())if(!t.has(n)||!_e(e.get(n),t.get(n)))return!1;break}case void 0:case Object:if(ke(e)!==ke(t))return!1;for(let n in e)if(!Se(e,n)||!_e(e[n],t[n]))return!1;break;case Array:if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!_e(e[n],t[n]))return!1;break;default:return!1}return!0},ks=(e,t)=>t.includes(e);var Ue=typeof process!="undefined"&&process.release&&/node|io\.js/.test(process.release.name)&&Object.prototype.toString.call(typeof process!="undefined"?process:0)==="[object process]";var ma=typeof navigator!="undefined"?/Mac/.test(navigator.platform):!1,Z,Fo=[],jo=()=>{if(Z===void 0)if(Ue){Z=A();let e=process.argv,t=null;for(let n=0;n<e.length;n++){let r=e[n];r[0]==="-"?(t!==null&&Z.set(t,""),t=r):t!==null?(Z.set(t,r),t=null):Fo.push(r)}t!==null&&Z.set(t,"")}else typeof location=="object"?(Z=A(),(location.search||"?").slice(1).split("&").forEach(e=>{if(e.length!==0){let[t,n]=e.split("=");Z.set(`--${Kn(t,"-")}`,n),Z.set(`-${Kn(t,"-")}`,n)}})):Z=A();return Z},hr=e=>jo().has(e);var ur=e=>Ue?rr(process.env[e.toUpperCase().replaceAll("-","_")]):rr(ms.getItem(e));var Ss=e=>hr("--"+e)||ur(e)!==null,_s=Ss("production"),qo=Ue&&ks(process.env.FORCE_COLOR,["true","1","2"]),Es=qo||!hr("--no-colors")&&!Ss("no-color")&&(!Ue||process.stdout.isTTY)&&(!Ue||hr("--color")||ur("COLORTERM")!==null||(ur("TERM")||"").includes("color"));var Go=e=>new Uint8Array(e);var Cs=e=>{let t=Go(e.byteLength);return t.set(e),t};var dr=class{constructor(t,n){this.left=t,this.right=n}},Q=(e,t)=>new dr(e,t);var fr=e=>e.next()>=.5,on=(e,t,n)=>B(e.next()*(n+1-t)+t);var pr=(e,t,n)=>B(e.next()*(n+1-t)+t);var gr=(e,t,n)=>pr(e,t,n);var Jo=e=>Pn(gr(e,97,122)),As=(e,t=0,n=20)=>{let r=gr(e,t,n),s="";for(let i=0;i<r;i++)s+=Jo(e);return s};var cn=(e,t)=>t[gr(e,0,t.length-1)];var Po=Symbol("0schema"),mr=class{constructor(){this._rerrs=[]}extend(t,n,r,s=null){this._rerrs.push({path:t,expected:n,has:r,message:s})}toString(){let t=[];for(let n=this._rerrs.length-1;n>0;n--){let r=this._rerrs[n];t.push(Qe(" ",(this._rerrs.length-n)*2)+`${r.path!=null?`[${r.path}] `:""}${r.has} doesn't match ${r.expected}. ${r.message}`)}return t.join(`
|
|
11303
|
+
`)}},wr=(e,t)=>e===t?!0:e==null||t==null||e.constructor!==t.constructor?!1:e[Ut]?sn(e,t):it(e)?Ye(e,n=>fe(t,r=>wr(n,r))):ws(e)?Wt(e,(n,r)=>wr(n,t[r])):!1,v=class{extends(t){let[n,r]=[this.shape,t.shape];return this.constructor._dilutes&&([r,n]=[n,r]),wr(n,r)}equals(t){return this.constructor===t.constructor&&_e(this.shape,t.shape)}[Po](){return!0}[Ut](t){return this.equals(t)}validate(t){return this.check(t)}check(t,n){H()}get nullable(){return re(this,bn)}get optional(){return new ln(this)}cast(t){return Is(t,this),t}expect(t){return Is(t,this),t}};Xe(v,"_dilutes",!1);var Ce=class extends v{constructor(t,n){super(),this.shape=t,this._c=n}check(t,n=void 0){let r=(t==null?void 0:t.constructor)===this.shape&&(this._c==null||this._c(t));return!r&&(n==null||n.extend(null,this.shape.name,t==null?void 0:t.constructor.name,(t==null?void 0:t.constructor)!==this.shape?"Constructor match failed":"Check failed")),r}},U=(e,t=null)=>new Ce(e,t),ya=U(Ce),Ae=class extends v{constructor(t){super(),this.shape=t}check(t,n){let r=this.shape(t);return!r&&(n==null||n.extend(null,"custom prop",t==null?void 0:t.constructor.name,"failed to check custom prop")),r}},I=e=>new Ae(e),xa=U(Ae),ee=class extends v{constructor(t){super(),this.shape=t}check(t,n){let r=this.shape.some(s=>s===t);return!r&&(n==null||n.extend(null,this.shape.join(" | "),t.toString())),r}},yn=(...e)=>new ee(e),Ts=U(ee),Ko=RegExp.escape||(e=>e.replace(/[().|&,$^[\]]/g,t=>"\\"+t)),Ds=e=>{if(ne.check(e))return[Ko(e)];if(Ts.check(e))return e.shape.map(t=>t+"");if(Ls.check(e))return["[+-]?\\d+.?\\d*"];if(Bs.check(e))return[".*"];if(gn.check(e))return e.shape.map(Ds).flat(1);D()},yr=class extends v{constructor(t){super(),this.shape=t,this._r=new RegExp("^"+t.map(Ds).map(n=>`(${n.join("|")})`).join("")+"$")}check(t,n){let r=this._r.exec(t)!=null;return!r&&(n==null||n.extend(null,this._r.toString(),t.toString(),"String doesn't match string template.")),r}};var ba=U(yr),Yo=Symbol("optional"),ln=class extends v{constructor(t){super(),this.shape=t}check(t,n){let r=t===void 0||this.shape.check(t);return!r&&(n==null||n.extend(null,"undefined (optional)","()")),r}get[Yo](){return!0}},Wo=U(ln),an=class extends v{check(t,n){return n==null||n.extend(null,"never",typeof t),!1}},ka=new an,Sa=U(an),wn=class wn extends v{constructor(t,n=!1){super(),this.shape=t,this._isPartial=n}get partial(){return new wn(this.shape,!0)}check(t,n){return t==null?(n==null||n.extend(null,"object","null"),!1):Wt(this.shape,(r,s)=>{let i=this._isPartial&&!Se(t,s)||r.check(t[s],n);return!i&&(n==null||n.extend(s.toString(),r.toString(),typeof t[s],"Object property does not match")),i})}};Xe(wn,"_dilutes",!0);var hn=wn,Zo=e=>new hn(e),Qo=U(hn),tc=I(e=>e!=null&&(e.constructor===Object||e.constructor==null)),un=class extends v{constructor(t,n){super(),this.shape={keys:t,values:n}}check(t,n){return t!=null&&Wt(t,(r,s)=>{let i=this.shape.keys.check(s,n);return!i&&(n==null||n.extend(s+"","Record",typeof t,i?"Key doesn't match schema":"Value doesn't match value")),i&&this.shape.values.check(r,n)})}},vs=(e,t)=>new un(e,t),ec=U(un),dn=class extends v{constructor(t){super(),this.shape=t}check(t,n){return t!=null&&Wt(this.shape,(r,s)=>{let i=r.check(t[s],n);return!i&&(n==null||n.extend(s.toString(),"Tuple",typeof r)),i})}},nc=(...e)=>new dn(e),_a=U(dn),fn=class extends v{constructor(t){super(),this.shape=t.length===1?t[0]:new Qt(t)}check(t,n){let r=it(t)&&Ye(t,s=>this.shape.check(s));return!r&&(n==null||n.extend(null,"Array","")),r}},Vs=(...e)=>new fn(e),rc=U(fn),sc=I(e=>it(e)),pn=class extends v{constructor(t,n){super(),this.shape=t,this._c=n}check(t,n){let r=t instanceof this.shape&&(this._c==null||this._c(t));return!r&&(n==null||n.extend(null,this.shape.name,t==null?void 0:t.constructor.name)),r}},ic=(e,t=null)=>new pn(e,t),Ea=U(pn),oc=ic(v),xr=class extends v{constructor(t){super(),this.len=t.length-1,this.args=nc(...t.slice(-1)),this.res=t[this.len]}check(t,n){let r=t.constructor===Function&&t.length<=this.len;return!r&&(n==null||n.extend(null,"function",typeof t)),r}};var cc=U(xr),lc=I(e=>typeof e=="function"),br=class extends v{constructor(t){super(),this.shape=t}check(t,n){let r=Ye(this.shape,s=>s.check(t,n));return!r&&(n==null||n.extend(null,"Intersectinon",typeof t)),r}};var Ua=U(br,e=>e.shape.length>0),Qt=class extends v{constructor(t){super(),this.shape=t}check(t,n){let r=fe(this.shape,s=>s.check(t,n));return n==null||n.extend(null,"Union",typeof t),r}};Xe(Qt,"_dilutes",!0);var re=(...e)=>e.findIndex(t=>gn.check(t))>=0?re(...e.map(t=>Ie(t)).map(t=>gn.check(t)?t.shape:[t]).flat(1)):e.length===1?e[0]:new Qt(e),gn=U(Qt),Os=()=>!0,mn=I(Os),ac=U(Ae,e=>e.shape===Os),Sr=I(e=>typeof e=="bigint"),hc=I(e=>e===Sr),Ns=I(e=>typeof e=="symbol"),Ca=I(e=>e===Ns),te=I(e=>typeof e=="number"),Ls=I(e=>e===te),ne=I(e=>typeof e=="string"),Bs=I(e=>e===ne),xn=I(e=>typeof e=="boolean"),uc=I(e=>e===xn),Ms=yn(void 0),Aa=U(ee,e=>e.shape.length===1&&e.shape[0]===void 0),Ia=yn(void 0);var bn=yn(null),dc=U(ee,e=>e.shape.length===1&&e.shape[0]===null),Ta=U(Uint8Array),Da=U(Ce,e=>e.shape===Uint8Array),fc=re(te,ne,bn,Ms,Sr,xn,Ns),va=(()=>{let e=Vs(mn),t=vs(ne,mn),n=re(te,ne,bn,xn,e,t);return e.shape=n,t.shape.values=n,n})(),Ie=e=>{if(oc.check(e))return e;if(tc.check(e)){let t={};for(let n in e)t[n]=Ie(e[n]);return Zo(t)}else{if(sc.check(e))return re(...e.map(Ie));if(fc.check(e))return yn(e);if(lc.check(e))return U(e)}D()},Is=_s?()=>{}:(e,t)=>{let n=new mr;if(!t.check(e,n))throw z(`Expected value to be of type ${t.constructor.name}.
|
|
11304
|
+
${n.toString()}`)},kr=class{constructor(t){this.patterns=[],this.$state=t}if(t,n){return this.patterns.push({if:Ie(t),h:n}),this}else(t){return this.if(mn,t)}done(){return(t,n)=>{for(let r=0;r<this.patterns.length;r++){let s=this.patterns[r];if(s.if.check(t))return s.h(t,n)}throw z("Unhandled pattern")}}},pc=e=>new kr(e),Rs=pc(mn).if(Ls,(e,t)=>on(t,Jn,Ft)).if(Bs,(e,t)=>As(t)).if(uc,(e,t)=>fr(t)).if(hc,(e,t)=>BigInt(on(t,Jn,Ft))).if(gn,(e,t)=>Zt(t,cn(t,e.shape))).if(Qo,(e,t)=>{let n={};for(let r in e.shape){let s=e.shape[r];if(Wo.check(s)){if(fr(t))continue;s=s.shape}n[r]=Rs(s,t)}return n}).if(rc,(e,t)=>{let n=[],r=pr(t,0,42);for(let s=0;s<r;s++)n.push(Zt(t,e.shape));return n}).if(Ts,(e,t)=>cn(t,e.shape)).if(dc,(e,t)=>null).if(cc,(e,t)=>{let n=Zt(t,e.res);return()=>n}).if(ac,(e,t)=>Zt(t,cn(t,[te,ne,bn,Ms,Sr,xn,Vs(te),vs(re("a","b","c"),te)]))).if(ec,(e,t)=>{let n={},r=on(t,0,3);for(let s=0;s<r;s++){let i=Zt(t,e.shape.keys),o=Zt(t,e.shape.values);n[i]=o}return n}).done(),Zt=(e,t)=>Rs(Ie(t),e);var Ct=typeof document!="undefined"?document:{};var Oa=I(e=>e.nodeType===xc);var Na=typeof DOMParser!="undefined"?new DOMParser:null;var La=I(e=>e.nodeType===mc);var Ba=I(e=>e.nodeType===wc);var $s=e=>ts(e,(t,n)=>`${n}:${t};`).join("");var mc=Ct.ELEMENT_NODE,wc=Ct.TEXT_NODE,Ma=Ct.CDATA_SECTION_NODE,Ra=Ct.COMMENT_NODE,yc=Ct.DOCUMENT_NODE,$a=Ct.DOCUMENT_TYPE_NODE,xc=Ct.DOCUMENT_FRAGMENT_NODE,Fa=I(e=>e.nodeType===yc);var tt=Symbol;var Te=tt(),De=tt(),_r=tt(),Er=tt(),Ur=tt(),ve=tt(),Cr=tt(),se=tt(),Ar=tt(),Fs=e=>{var s;e.length===1&&((s=e[0])==null?void 0:s.constructor)===Function&&(e=e[0]());let t=[],n=[],r=0;for(;r<e.length;r++){let i=e[r];if(i===void 0)break;if(i.constructor===String||i.constructor===Number)t.push(i);else if(i.constructor===Object)break}for(r>0&&n.push(t.join(""));r<e.length;r++){let i=e[r];i instanceof Symbol||n.push(i)}return n};var ja=rn();var _c={[Te]:Q("font-weight","bold"),[De]:Q("font-weight","normal"),[_r]:Q("color","blue"),[Ur]:Q("color","green"),[Er]:Q("color","grey"),[ve]:Q("color","red"),[Cr]:Q("color","purple"),[se]:Q("color","orange"),[Ar]:Q("color","black")},Ec=e=>{var o;e.length===1&&((o=e[0])==null?void 0:o.constructor)===Function&&(e=e[0]());let t=[],n=[],r=A(),s=[],i=0;for(;i<e.length;i++){let c=e[i],l=_c[c];if(l!==void 0)r.set(l.left,l.right);else{if(c===void 0)break;if(c.constructor===String||c.constructor===Number){let u=$s(r);i>0||u.length>0?(t.push("%c"+c),n.push(u)):t.push(c)}else break}}for(i>0&&(s=n,s.unshift(t.join("")));i<e.length;i++){let c=e[i];c instanceof Symbol||s.push(c)}return s},js=Es?Ec:Fs,kn=(...e)=>{console.log(...js(e)),Gs.forEach(t=>t.print(e))},qs=(...e)=>{console.warn(...js(e)),e.unshift(se),Gs.forEach(t=>t.print(e))};var Gs=st();var zs=e=>({[Symbol.iterator](){return this},next:e}),Hs=(e,t)=>zs(()=>{let n;do n=e.next();while(!n.done&&!t(n.value));return n}),Sn=(e,t)=>zs(()=>{let{done:n,value:r}=e.next();return{done:n,value:n?void 0:t(r)}});var Tr=class extends $t{constructor(t,n){super(),this.doc=t,this.awareness=n}},Ne=class{constructor(t,n){this.clock=t,this.len=n}},mt=class{constructor(){this.clients=new Map}},It=(e,t,n)=>t.clients.forEach((r,s)=>{let i=e.doc.store.clients.get(s);for(let o=0;o<r.length;o++){let c=r[o];yi(e,i,c.clock,c.len,n)}}),Tc=(e,t)=>{let n=0,r=e.length-1;for(;n<=r;){let s=B((n+r)/2),i=e[s],o=i.clock;if(o<=t){if(t<o+i.len)return s;n=s+1}else r=s-1}return null},Rt=(e,t)=>{let n=e.clients.get(t.client);return n!==void 0&&Tc(n,t.clock)!==null},$r=e=>{e.clients.forEach(t=>{t.sort((s,i)=>s.clock-i.clock);let n,r;for(n=1,r=1;n<t.length;n++){let s=t[r-1],i=t[n];s.clock+s.len>=i.clock?s.len=ot(s.len,i.clock+i.len-s.clock):(r<n&&(t[r]=i),r++)}t.length=r})},ie=e=>{let t=new mt;for(let n=0;n<e.length;n++)e[n].clients.forEach((r,s)=>{if(!t.clients.has(s)){let i=r.slice();for(let o=n+1;o<e.length;o++)ns(i,e[o].clients.get(s)||[]);t.clients.set(s,i)}});return $r(t),t},Le=(e,t,n,r)=>{L(e.clients,t,()=>[]).push(new Ne(n,r))},Fn=()=>new mt,Fr=e=>{let t=Fn();return e.clients.forEach((n,r)=>{let s=[];for(let i=0;i<n.length;i++){let o=n[i];if(o.deleted){let c=o.id.clock,l=o.length;if(i+1<n.length)for(let u=n[i+1];i+1<n.length&&u.deleted;u=n[++i+1])l+=u.length;s.push(new Ne(c,l))}}s.length>0&&t.clients.set(r,s)}),t},et=(e,t)=>{g(e.restEncoder,t.clients.size),W(t.clients.entries()).sort((n,r)=>r[0]-n[0]).forEach(([n,r])=>{e.resetDsCurVal(),g(e.restEncoder,n);let s=r.length;g(e.restEncoder,s);for(let i=0;i<s;i++){let o=r[i];e.writeDsClock(o.clock),e.writeDsLen(o.len)}})},lt=e=>{let t=new mt,n=y(e.restDecoder);for(let r=0;r<n;r++){e.resetDsCurVal();let s=y(e.restDecoder),i=y(e.restDecoder);if(i>0){let o=L(t.clients,s,()=>[]);for(let c=0;c<i;c++)o.push(new Ne(e.readDsClock(),e.readDsLen()))}}return t},Ps=(e,t,n)=>{let r=new mt,s=y(e.restDecoder);for(let i=0;i<s;i++){e.resetDsCurVal();let o=y(e.restDecoder),c=y(e.restDecoder),l=n.clients.get(o)||[],u=_(n,o);for(let a=0;a<c;a++){let h=e.readDsClock(),d=h+e.readDsLen();if(h<u){u<d&&Le(r,o,u,d-u);let f=P(l,h),p=l[f];for(!p.deleted&&p.id.clock<h&&(l.splice(f+1,0,$n(t,p,h-p.id.clock)),f++);f<l.length&&(p=l[f++],p.id.clock<d);)p.deleted||(d<p.id.clock+p.length&&l.splice(f,0,$n(t,p,d-p.id.clock)),p.delete(t))}else Le(r,o,h,d-h)}}if(r.clients.size>0){let i=new J;return g(i.restEncoder,0),et(i,r),i.toUint8Array()}return null},hi=(e,t)=>{if(e.clients.size!==t.clients.size)return!1;for(let[n,r]of e.clients.entries()){let s=t.clients.get(n);if(s===void 0||r.length!==s.length)return!1;for(let i=0;i<r.length;i++){let o=r[i],c=s[i];if(o.clock!==c.clock||o.len!==c.len)return!1}}return!0},ui=er,Tt=class e extends $t{constructor({guid:t=fs(),collectionid:n=null,gc:r=!0,gcFilter:s=()=>!0,meta:i=null,autoLoad:o=!1,shouldLoad:c=!0}={}){super(),this.gc=r,this.gcFilter=s,this.clientID=ui(),this.guid=t,this.collectionid=n,this.share=new Map,this.store=new Dn,this._transaction=null,this._transactionCleanups=[],this.subdocs=new Set,this._item=null,this.shouldLoad=c,this.autoLoad=o,this.meta=i,this.isLoaded=!1,this.isSynced=!1,this.whenLoaded=nr(u=>{this.on("load",()=>{this.isLoaded=!0,u(this)})});let l=()=>nr(u=>{let a=h=>{(h===void 0||h===!0)&&(this.off("sync",a),u())};this.on("sync",a)});this.on("sync",u=>{u===!1&&this.isSynced&&(this.whenSynced=l()),this.isSynced=u===void 0||u===!0,this.isSynced&&!this.isLoaded&&this.emit("load",[this])}),this.whenSynced=l()}load(){let t=this._item;t!==null&&!this.shouldLoad&&k(t.parent.doc,n=>{n.subdocsLoaded.add(this)},null,!0),this.shouldLoad=!0}getSubdocs(){return this.subdocs}getSubdocGuids(){return new Set(W(this.subdocs).map(t=>t.guid))}transact(t,n=null){return k(this,t,n)}get(t,n=C){let r=L(this.share,t,()=>{let i=new n;return i._integrate(this,null),i}),s=r.constructor;if(n!==C&&s!==n)if(s===C){let i=new n;i._map=r._map,r._map.forEach(o=>{for(;o!==null;o=o.left)o.parent=i}),i._start=r._start;for(let o=i._start;o!==null;o=o.right)o.parent=i;return i._length=r._length,this.share.set(t,i),i._integrate(this,null),i}else throw new Error(`Type with the name ${t} has already been defined with a different constructor`);return r}getArray(t=""){return this.get(t,Vt)}getText(t=""){return this.get(t,le)}getMap(t=""){return this.get(t,Ot)}getXmlElement(t=""){return this.get(t,Lt)}getXmlFragment(t=""){return this.get(t,Nt)}toJSON(){let t={};return this.share.forEach((n,r)=>{t[r]=n.toJSON()}),t}destroy(){W(this.subdocs).forEach(n=>n.destroy());let t=this._item;if(t!==null){this._item=null;let n=t.content;n.doc=new e({guid:this.guid,...n.opts,shouldLoad:!1}),n.doc._item=t,k(t.parent.doc,r=>{let s=n.doc;t.deleted||r.subdocsAdded.add(s),r.subdocsRemoved.add(this)},null,!0)}this.emit("destroyed",[!0]),this.emit("destroy",[this]),super.destroy()}},Dt=class{constructor(t){this.restDecoder=t}resetDsCurVal(){}readDsClock(){return y(this.restDecoder)}readDsLen(){return y(this.restDecoder)}},j=class extends Dt{readLeftID(){return w(y(this.restDecoder),y(this.restDecoder))}readRightID(){return w(y(this.restDecoder),y(this.restDecoder))}readClient(){return y(this.restDecoder)}readInfo(){return _t(this.restDecoder)}readString(){return dt(this.restDecoder)}readParentInfo(){return y(this.restDecoder)===1}readTypeRef(){return y(this.restDecoder)}readLen(){return y(this.restDecoder)}readAny(){return Kt(this.restDecoder)}readBuf(){return Cs(F(this.restDecoder))}readJSON(){return JSON.parse(dt(this.restDecoder))}readKey(){return dt(this.restDecoder)}},In=class{constructor(t){this.dsCurrVal=0,this.restDecoder=t}resetDsCurVal(){this.dsCurrVal=0}readDsClock(){return this.dsCurrVal+=y(this.restDecoder),this.dsCurrVal}readDsLen(){let t=y(this.restDecoder)+1;return this.dsCurrVal+=t,t}},R=class extends In{constructor(t){super(t),this.keys=[],y(t),this.keyClockDecoder=new Yt(F(t)),this.clientDecoder=new Et(F(t)),this.leftClockDecoder=new Yt(F(t)),this.rightClockDecoder=new Yt(F(t)),this.infoDecoder=new xe(F(t),_t),this.stringDecoder=new en(F(t)),this.parentInfoDecoder=new xe(F(t),_t),this.typeRefDecoder=new Et(F(t)),this.lenDecoder=new Et(F(t))}readLeftID(){return new ct(this.clientDecoder.read(),this.leftClockDecoder.read())}readRightID(){return new ct(this.clientDecoder.read(),this.rightClockDecoder.read())}readClient(){return this.clientDecoder.read()}readInfo(){return this.infoDecoder.read()}readString(){return this.stringDecoder.read()}readParentInfo(){return this.parentInfoDecoder.read()===1}readTypeRef(){return this.typeRefDecoder.read()}readLen(){return this.lenDecoder.read()}readAny(){return Kt(this.restDecoder)}readBuf(){return F(this.restDecoder)}readJSON(){return Kt(this.restDecoder)}readKey(){let t=this.keyClockDecoder.read();if(t<this.keys.length)return this.keys[t];{let n=this.stringDecoder.read();return this.keys.push(n),n}}},wt=class{constructor(){this.restEncoder=St()}toUint8Array(){return G(this.restEncoder)}resetDsCurVal(){}writeDsClock(t){g(this.restEncoder,t)}writeDsLen(t){g(this.restEncoder,t)}},nt=class extends wt{writeLeftID(t){g(this.restEncoder,t.client),g(this.restEncoder,t.clock)}writeRightID(t){g(this.restEncoder,t.client),g(this.restEncoder,t.clock)}writeClient(t){g(this.restEncoder,t)}writeInfo(t){Jt(this.restEncoder,t)}writeString(t){ht(this.restEncoder,t)}writeParentInfo(t){g(this.restEncoder,t?1:0)}writeTypeRef(t){g(this.restEncoder,t)}writeLen(t){g(this.restEncoder,t)}writeAny(t){zt(this.restEncoder,t)}writeBuf(t){$(this.restEncoder,t)}writeJSON(t){ht(this.restEncoder,JSON.stringify(t))}writeKey(t){ht(this.restEncoder,t)}},oe=class{constructor(){this.restEncoder=St(),this.dsCurrVal=0}toUint8Array(){return G(this.restEncoder)}resetDsCurVal(){this.dsCurrVal=0}writeDsClock(t){let n=t-this.dsCurrVal;this.dsCurrVal=t,g(this.restEncoder,n)}writeDsLen(t){t===0&&D(),g(this.restEncoder,t-1),this.dsCurrVal+=t}},J=class extends oe{constructor(){super(),this.keyMap=new Map,this.keyClock=0,this.keyClockEncoder=new Ht,this.clientEncoder=new kt,this.leftClockEncoder=new Ht,this.rightClockEncoder=new Ht,this.infoEncoder=new we(Jt),this.stringEncoder=new tn,this.parentInfoEncoder=new we(Jt),this.typeRefEncoder=new kt,this.lenEncoder=new kt}toUint8Array(){let t=St();return g(t,0),$(t,this.keyClockEncoder.toUint8Array()),$(t,this.clientEncoder.toUint8Array()),$(t,this.leftClockEncoder.toUint8Array()),$(t,this.rightClockEncoder.toUint8Array()),$(t,G(this.infoEncoder)),$(t,this.stringEncoder.toUint8Array()),$(t,G(this.parentInfoEncoder)),$(t,this.typeRefEncoder.toUint8Array()),$(t,this.lenEncoder.toUint8Array()),Xt(t,G(this.restEncoder)),G(t)}writeLeftID(t){this.clientEncoder.write(t.client),this.leftClockEncoder.write(t.clock)}writeRightID(t){this.clientEncoder.write(t.client),this.rightClockEncoder.write(t.clock)}writeClient(t){this.clientEncoder.write(t)}writeInfo(t){this.infoEncoder.write(t)}writeString(t){this.stringEncoder.write(t)}writeParentInfo(t){this.parentInfoEncoder.write(t?1:0)}writeTypeRef(t){this.typeRefEncoder.write(t)}writeLen(t){this.lenEncoder.write(t)}writeAny(t){zt(this.restEncoder,t)}writeBuf(t){$(this.restEncoder,t)}writeJSON(t){zt(this.restEncoder,t)}writeKey(t){let n=this.keyMap.get(t);n===void 0?(this.keyClockEncoder.write(this.keyClock++),this.stringEncoder.write(t)):this.keyClockEncoder.write(n)}},Dc=(e,t,n,r)=>{r=ot(r,t[0].id.clock);let s=P(t,r);g(e.restEncoder,t.length-s),e.writeClient(n),g(e.restEncoder,r);let i=t[s];i.write(e,r-i.id.clock);for(let o=s+1;o<t.length;o++)t[o].write(e,0)},jr=(e,t,n)=>{let r=new Map;n.forEach((s,i)=>{_(t,i)>s&&r.set(i,s)}),He(t).forEach((s,i)=>{n.has(i)||r.set(i,0)}),g(e.restEncoder,r.size),W(r.entries()).sort((s,i)=>i[0]-s[0]).forEach(([s,i])=>{Dc(e,t.clients.get(s),s,i)})},vc=(e,t)=>{let n=A(),r=y(e.restDecoder);for(let s=0;s<r;s++){let i=y(e.restDecoder),o=new Array(i),c=e.readClient(),l=y(e.restDecoder);n.set(c,{i:0,refs:o});for(let u=0;u<i;u++){let a=e.readInfo();switch(31&a){case 0:{let h=e.readLen();o[u]=new N(w(c,l),h),l+=h;break}case 10:{let h=y(e.restDecoder);o[u]=new O(w(c,l),h),l+=h;break}default:{let h=(a&192)===0,d=new S(w(c,l),null,(a&128)===128?e.readLeftID():null,null,(a&64)===64?e.readRightID():null,h?e.readParentInfo()?t.get(e.readString()):e.readLeftID():null,h&&(a&32)===32?e.readString():null,Ki(e,a));o[u]=d,l+=d.length}}}}return n},Vc=(e,t,n)=>{let r=[],s=W(n.keys()).sort((f,p)=>f-p);if(s.length===0)return null;let i=()=>{if(s.length===0)return null;let f=n.get(s[s.length-1]);for(;f.refs.length===f.i;)if(s.pop(),s.length>0)f=n.get(s[s.length-1]);else return null;return f},o=i();if(o===null)return null;let c=new Dn,l=new Map,u=(f,p)=>{let b=l.get(f);(b==null||b>p)&&l.set(f,p)},a=o.refs[o.i++],h=new Map,d=()=>{for(let f of r){let p=f.id.client,b=n.get(p);b?(b.i--,c.clients.set(p,b.refs.slice(b.i)),n.delete(p),b.i=0,b.refs=[]):c.clients.set(p,[f]),s=s.filter(m=>m!==p)}r.length=0};for(;;){if(a.constructor!==O){let p=L(h,a.id.client,()=>_(t,a.id.client))-a.id.clock;if(p<0)r.push(a),u(a.id.client,a.id.clock-1),d();else{let b=a.getMissing(e,t);if(b!==null){r.push(a);let m=n.get(b)||{refs:[],i:0};if(m.refs.length===m.i)u(b,_(t,b)),d();else{a=m.refs[m.i++];continue}}else(p===0||p<a.length)&&(a.integrate(e,p),h.set(a.id.client,a.id.clock+a.length))}}if(r.length>0)a=r.pop();else if(o!==null&&o.i<o.refs.length)a=o.refs[o.i++];else{if(o=i(),o===null)break;a=o.refs[o.i++]}}if(c.clients.size>0){let f=new J;return jr(f,c,new Map),g(f.restEncoder,0),{missing:l,update:f.toUint8Array()}}return null},Oc=(e,t)=>jr(e,t.doc.store,t.beforeState),qr=(e,t,n,r=new R(e))=>k(t,s=>{s.local=!1;let i=!1,o=s.doc,c=o.store,l=vc(r,o),u=Vc(s,c,l),a=c.pendingStructs;if(a){for(let[d,f]of a.missing)if(f<_(c,d)){i=!0;break}if(u){for(let[d,f]of u.missing){let p=a.missing.get(d);(p==null||p>f)&&a.missing.set(d,f)}a.update=$e([a.update,u.update])}}else c.pendingStructs=u;let h=Ps(r,s,c);if(c.pendingDs){let d=new R(V(c.pendingDs));y(d.restDecoder);let f=Ps(d,s,c);h&&f?c.pendingDs=$e([h,f]):c.pendingDs=h||f}else c.pendingDs=h;if(i){let d=c.pendingStructs.update;c.pendingStructs=null,jn(s.doc,d)}},n,!1),Nc=(e,t,n)=>qr(e,t,n,new j(e)),jn=(e,t,n,r=R)=>{let s=V(t);qr(s,e,n,new r(s))},Lc=(e,t,n)=>jn(e,t,n,j),Bc=(e,t,n=new Map)=>{jr(e,t.store,n),et(e,Fr(t.store))},di=(e,t=new Uint8Array([0]),n=new J)=>{let r=Gr(t);Bc(n,e,r);let s=[n.toUint8Array()];if(e.store.pendingDs&&s.push(e.store.pendingDs),e.store.pendingStructs&&s.push(Xr(e.store.pendingStructs.update,t)),s.length>1){if(n.constructor===nt)return Ei(s.map((i,o)=>o===0?i:Ti(i)));if(n.constructor===J)return $e(s)}return s[0]},Mc=(e,t)=>di(e,t,new nt),fi=e=>{let t=new Map,n=y(e.restDecoder);for(let r=0;r<n;r++){let s=y(e.restDecoder),i=y(e.restDecoder);t.set(s,i)}return t},Gr=e=>fi(new Dt(V(e))),zr=(e,t)=>(g(e.restEncoder,t.size),W(t.entries()).sort((n,r)=>r[0]-n[0]).forEach(([n,r])=>{g(e.restEncoder,n),g(e.restEncoder,r)}),e),Rc=(e,t)=>zr(e,He(t.store)),$c=(e,t=new oe)=>(e instanceof Map?zr(t,e):Rc(t,e),t.toUint8Array()),Fc=e=>$c(e,new wt),Dr=class{constructor(){this.l=[]}},Ks=()=>new Dr,Ys=(e,t)=>e.l.push(t),Ws=(e,t)=>{let n=e.l,r=n.length;e.l=n.filter(s=>t!==s),r===e.l.length&&console.error("[yjs] Tried to remove event handler that doesn't exist.")},pi=(e,t,n)=>Ee(e.l,[t,n]),ct=class{constructor(t,n){this.client=t,this.clock=n}},At=(e,t)=>e===t||e!==null&&t!==null&&e.client===t.client&&e.clock===t.clock,w=(e,t)=>new ct(e,t),Zs=(e,t)=>{g(e,t.client),g(e,t.clock)},Qs=e=>w(y(e),y(e)),Hr=e=>{for(let[t,n]of e.doc.share.entries())if(n===e)return t;throw D()},Be=(e,t)=>{for(;t!==null;){if(t.parent===e)return!0;t=t.parent._item}return!1},jc=e=>{let t=[],n=e._start;for(;n;)t.push(n),n=n.right;console.log("Children: ",t),console.log("Children content: ",t.filter(r=>!r.deleted).map(r=>r.content))},vr=class{constructor(t,n=t.getMap("users")){let r=new Map;this.yusers=n,this.doc=t,this.clients=new Map,this.dss=r;let s=(i,o)=>{let c=i.get("ds"),l=i.get("ids"),u=a=>this.clients.set(a,o);c.observe(a=>{a.changes.added.forEach(h=>{h.content.getContent().forEach(d=>{d instanceof Uint8Array&&this.dss.set(o,ie([this.dss.get(o)||Fn(),lt(new Dt(V(d)))]))})})}),this.dss.set(o,ie(c.map(a=>lt(new Dt(V(a)))))),l.observe(a=>a.changes.added.forEach(h=>h.content.getContent().forEach(u))),l.forEach(u)};n.observe(i=>{i.keysChanged.forEach(o=>s(n.get(o),o))}),n.forEach(s)}setUserMapping(t,n,r,{filter:s=()=>!0}={}){let i=this.yusers,o=i.get(r);o||(o=new Ot,o.set("ids",new Vt),o.set("ds",new Vt),i.set(r,o)),o.get("ids").push([n]),i.observe(c=>{setTimeout(()=>{let l=i.get(r);if(l!==o){o=l,this.clients.forEach((h,d)=>{r===h&&o.get("ids").push([d])});let u=new wt,a=this.dss.get(r);a&&(et(u,a),o.get("ds").push([u.toUint8Array()]))}},0)}),t.on("afterTransaction",c=>{setTimeout(()=>{let l=o.get("ds"),u=c.deleteSet;if(c.local&&u.clients.size>0&&s(c,u)){let a=new wt;et(a,u),l.push([a.toUint8Array()])}})})}getUserByClientId(t){return this.clients.get(t)||null}getUserByDeletedId(t){for(let[n,r]of this.dss.entries())if(Rt(r,t))return n;return null}},ce=class{constructor(t,n,r,s=0){this.type=t,this.tname=n,this.item=r,this.assoc=s}},qc=e=>{let t={};return e.type&&(t.type=e.type),e.tname&&(t.tname=e.tname),e.item&&(t.item=e.item),e.assoc!=null&&(t.assoc=e.assoc),t},Gc=e=>new ce(e.type==null?null:w(e.type.client,e.type.clock),e.tname||null,e.item==null?null:w(e.item.client,e.item.clock),e.assoc==null?0:e.assoc),Tn=class{constructor(t,n,r=0){this.type=t,this.index=n,this.assoc=r}},zc=(e,t,n=0)=>new Tn(e,t,n),_n=(e,t,n)=>{let r=null,s=null;return e._item===null?s=Hr(e):r=w(e._item.id.client,e._item.id.clock),new ce(r,s,t,n)},Hc=(e,t,n=0)=>{let r=e._start;if(n<0){if(t===0)return _n(e,null,n);t--}for(;r!==null;){if(!r.deleted&&r.countable){if(r.length>t)return _n(e,w(r.id.client,r.id.clock+t),n);t-=r.length}if(r.right===null&&n<0)return _n(e,r.lastId,n);r=r.right}return _n(e,null,n)},Jc=(e,t)=>{let{type:n,tname:r,item:s,assoc:i}=t;if(s!==null)g(e,0),Zs(e,s);else if(r!==null)Jt(e,1),ht(e,r);else if(n!==null)Jt(e,2),Zs(e,n);else throw D();return ye(e,i),e},Xc=e=>{let t=St();return Jc(t,e),G(t)},Pc=e=>{let t=null,n=null,r=null;switch(y(e)){case 0:r=Qs(e);break;case 1:n=dt(e);break;case 2:t=Qs(e)}let s=Qn(e)?be(e):0;return new ce(t,n,r,s)},Kc=e=>Pc(V(e)),Yc=(e,t)=>{let n=t.store,r=e.item,s=e.type,i=e.tname,o=e.assoc,c=null,l=0;if(r!==null){if(_(n,r.client)<=r.clock)return null;let u=Mr(n,r),a=u.item;if(!(a instanceof S))return null;if(c=a.parent,c._item===null||!c._item.deleted){l=a.deleted||!a.countable?0:u.diff+(o>=0?0:1);let h=a.left;for(;h!==null;)!h.deleted&&h.countable&&(l+=h.length),h=h.left}}else{if(i!==null)c=t.get(i);else if(s!==null){if(_(n,s.client)<=s.clock)return null;let{item:u}=Mr(n,s);if(u instanceof S&&u.content instanceof K)c=u.content.type;else return null}else throw D();o>=0?l=c._length:l=0}return zc(c,l,e.assoc)},Wc=(e,t)=>e===t||e!==null&&t!==null&&e.tname===t.tname&&At(e.item,t.item)&&At(e.type,t.type)&&e.assoc===t.assoc,Me=class{constructor(t,n){this.ds=t,this.sv=n}},Zc=(e,t)=>{let n=e.ds.clients,r=t.ds.clients,s=e.sv,i=t.sv;if(s.size!==i.size||n.size!==r.size)return!1;for(let[o,c]of s.entries())if(i.get(o)!==c)return!1;for(let[o,c]of n.entries()){let l=r.get(o)||[];if(c.length!==l.length)return!1;for(let u=0;u<c.length;u++){let a=c[u],h=l[u];if(a.clock!==h.clock||a.len!==h.len)return!1}}return!0},gi=(e,t=new oe)=>(et(t,e.ds),zr(t,e.sv),t.toUint8Array()),Qc=e=>gi(e,new wt),mi=(e,t=new In(V(e)))=>new Me(lt(t),fi(t)),tl=e=>mi(e,new Dt(V(e))),Jr=(e,t)=>new Me(e,t),el=Jr(Fn(),new Map),nl=e=>Jr(Fr(e.store),He(e.store)),ft=(e,t)=>t===void 0?!e.deleted:t.sv.has(e.id.client)&&(t.sv.get(e.id.client)||0)>e.id.clock&&!Rt(t.ds,e.id),Vr=(e,t)=>{let n=L(e.meta,Vr,st),r=e.doc.store;n.has(t)||(t.sv.forEach((s,i)=>{s<_(r,i)&&M(e,w(i,s))}),It(e,t.ds,s=>{}),n.add(t))},rl=(e,t,n=new Tt)=>{if(e.gc)throw new Error("Garbage-collection must be disabled in `originDoc`!");let{sv:r,ds:s}=t,i=new J;return e.transact(o=>{let c=0;r.forEach(l=>{l>0&&c++}),g(i.restEncoder,c);for(let[l,u]of r){if(u===0)continue;u<_(e.store,l)&&M(o,w(l,u));let a=e.store.clients.get(l)||[],h=P(a,u-1);g(i.restEncoder,h+1),i.writeClient(l),g(i.restEncoder,0);for(let d=0;d<=h;d++)a[d].write(i,0)}et(i,s)}),jn(n,i.toUint8Array(),"snapshot"),n},sl=(e,t,n=R)=>{let r=new n(V(t)),s=new rt(r,!1);for(let o=s.curr;o!==null;o=s.next())if((e.sv.get(o.id.client)||0)<o.id.clock+o.length)return!1;let i=ie([e.ds,lt(r)]);return hi(e.ds,i)},il=(e,t)=>sl(e,t,j),Dn=class{constructor(){this.clients=new Map,this.pendingStructs=null,this.pendingDs=null}},He=e=>{let t=new Map;return e.clients.forEach((n,r)=>{let s=n[n.length-1];t.set(r,s.id.clock+s.length)}),t},_=(e,t)=>{let n=e.clients.get(t);if(n===void 0)return 0;let r=n[n.length-1];return r.id.clock+r.length},wi=(e,t)=>{let n=e.clients.get(t.id.client);if(n===void 0)n=[],e.clients.set(t.id.client,n);else{let r=n[n.length-1];if(r.id.clock+r.length!==t.id.clock)throw D()}n.push(t)},P=(e,t)=>{let n=0,r=e.length-1,s=e[r],i=s.id.clock;if(i===t)return r;let o=B(t/(i+s.length-1)*r);for(;n<=r;){if(s=e[o],i=s.id.clock,i<=t){if(t<i+s.length)return o;n=o+1}else r=o-1;o=B((n+r)/2)}throw D()},ol=(e,t)=>{let n=e.clients.get(t.client);return n[P(n,t.clock)]},Ve=ol,Or=(e,t,n)=>{let r=P(t,n),s=t[r];return s.id.clock<n&&s instanceof S?(t.splice(r+1,0,$n(e,s,n-s.id.clock)),r+1):r},M=(e,t)=>{let n=e.doc.store.clients.get(t.client);return n[Or(e,n,t.clock)]},ti=(e,t,n)=>{let r=t.clients.get(n.client),s=P(r,n.clock),i=r[s];return n.clock!==i.id.clock+i.length-1&&i.constructor!==N&&r.splice(s+1,0,$n(e,i,n.clock-i.id.clock+1)),i},cl=(e,t,n)=>{let r=e.clients.get(t.id.client);r[P(r,t.id.clock)]=n},yi=(e,t,n,r,s)=>{if(r===0)return;let i=n+r,o=Or(e,t,n),c;do c=t[o++],i<c.id.clock+c.length&&Or(e,t,i),s(c);while(o<t.length&&t[o].id.clock<i)},vn=class{constructor(t,n,r){this.doc=t,this.deleteSet=new mt,this.beforeState=He(t.store),this.afterState=new Map,this.changed=new Map,this.changedParentTypes=new Map,this._mergeStructs=[],this.origin=n,this.meta=new Map,this.local=r,this.subdocsAdded=new Set,this.subdocsRemoved=new Set,this.subdocsLoaded=new Set,this._needFormattingCleanup=!1}},ei=(e,t)=>t.deleteSet.clients.size===0&&!es(t.afterState,(n,r)=>t.beforeState.get(r)!==n)?!1:($r(t.deleteSet),Oc(e,t),et(e,t.deleteSet),!0),ni=(e,t,n)=>{let r=t._item;(r===null||r.id.clock<(e.beforeState.get(r.id.client)||0)&&!r.deleted)&&L(e.changed,t,st).add(n)},Cn=(e,t)=>{let n=e[t],r=e[t-1],s=t;for(;s>0;n=r,r=e[--s-1]){if(r.deleted===n.deleted&&r.constructor===n.constructor&&r.mergeWith(n)){n instanceof S&&n.parentSub!==null&&n.parent._map.get(n.parentSub)===n&&n.parent._map.set(n.parentSub,r);continue}break}let i=t-s;return i&&e.splice(t+1-i,i),i},xi=(e,t,n)=>{for(let[r,s]of e.clients.entries()){let i=t.clients.get(r);for(let o=s.length-1;o>=0;o--){let c=s[o],l=c.clock+c.len;for(let u=P(i,c.clock),a=i[u];u<i.length&&a.id.clock<l;a=i[++u]){let h=i[u];if(c.clock+c.len<=h.id.clock)break;h instanceof S&&h.deleted&&!h.keep&&n(h)&&h.gc(t,!1)}}}},bi=(e,t)=>{e.clients.forEach((n,r)=>{let s=t.clients.get(r);for(let i=n.length-1;i>=0;i--){let o=n[i],c=We(s.length-1,1+P(s,o.clock+o.len-1));for(let l=c,u=s[l];l>0&&u.id.clock>=o.clock;u=s[l])l-=1+Cn(s,l)}})},ll=(e,t,n)=>{xi(e,t,n),bi(e,t)},ki=(e,t)=>{if(t<e.length){let n=e[t],r=n.doc,s=r.store,i=n.deleteSet,o=n._mergeStructs;try{$r(i),n.afterState=He(n.doc.store),r.emit("beforeObserverCalls",[n,r]);let c=[];n.changed.forEach((l,u)=>c.push(()=>{(u._item===null||!u._item.deleted)&&u._callObserver(n,l)})),c.push(()=>{n.changedParentTypes.forEach((l,u)=>{u._dEH.l.length>0&&(u._item===null||!u._item.deleted)&&(l=l.filter(a=>a.target._item===null||!a.target._item.deleted),l.forEach(a=>{a.currentTarget=u,a._path=null}),l.sort((a,h)=>a.path.length-h.path.length),pi(u._dEH,l,n))})}),c.push(()=>r.emit("afterTransaction",[n,r])),Ee(c,[]),n._needFormattingCleanup&&Dl(n)}finally{r.gc&&xi(i,s,r.gcFilter),bi(i,s),n.afterState.forEach((a,h)=>{let d=n.beforeState.get(h)||0;if(d!==a){let f=s.clients.get(h),p=ot(P(f,d),1);for(let b=f.length-1;b>=p;)b-=1+Cn(f,b)}});for(let a=o.length-1;a>=0;a--){let{client:h,clock:d}=o[a].id,f=s.clients.get(h),p=P(f,d);p+1<f.length&&Cn(f,p+1)>1||p>0&&Cn(f,p)}if(!n.local&&n.afterState.get(r.clientID)!==n.beforeState.get(r.clientID)&&(kn(se,Te,"[yjs] ",De,ve,"Changed the client-id because another client seems to be using it."),r.clientID=ui()),r.emit("afterTransactionCleanup",[n,r]),r._observers.has("update")){let a=new nt;ei(a,n)&&r.emit("update",[a.toUint8Array(),n.origin,r,n])}if(r._observers.has("updateV2")){let a=new J;ei(a,n)&&r.emit("updateV2",[a.toUint8Array(),n.origin,r,n])}let{subdocsAdded:c,subdocsLoaded:l,subdocsRemoved:u}=n;(c.size>0||u.size>0||l.size>0)&&(c.forEach(a=>{a.clientID=r.clientID,a.collectionid==null&&(a.collectionid=r.collectionid),r.subdocs.add(a)}),u.forEach(a=>r.subdocs.delete(a)),r.emit("subdocs",[{loaded:l,added:c,removed:u},r,n]),u.forEach(a=>a.destroy())),e.length<=t+1?(r._transactionCleanups=[],r.emit("afterAllTransactions",[r,e])):ki(e,t+1)}}},k=(e,t,n=null,r=!0)=>{let s=e._transactionCleanups,i=!1,o=null;e._transaction===null&&(i=!0,e._transaction=new vn(e,n,r),s.push(e._transaction),s.length===1&&e.emit("beforeAllTransactions",[e]),e.emit("beforeTransaction",[e._transaction,e]));try{o=t(e._transaction)}finally{if(i){let c=e._transaction===s[0];e._transaction=null,c&&ki(s,0)}}return o},Nr=class{constructor(t,n){this.insertions=n,this.deletions=t,this.meta=new Map}},ri=(e,t,n)=>{It(e,n.deletions,r=>{r instanceof S&&t.scope.some(s=>Be(s,r))&&Zr(r,!1)})},si=(e,t,n)=>{let r=null,s=e.doc,i=e.scope;if(k(s,o=>{for(;t.length>0&&e.currStackItem===null;){let c=s.store,l=t.pop(),u=new Set,a=[],h=!1;It(o,l.insertions,d=>{if(d instanceof S){if(d.redone!==null){let{item:f,diff:p}=Mr(c,d.id);p>0&&(f=M(o,w(f.id.client,f.id.clock+p))),d=f}!d.deleted&&i.some(f=>Be(f,d))&&a.push(d)}}),It(o,l.deletions,d=>{d instanceof S&&i.some(f=>Be(f,d))&&!Rt(l.insertions,d.id)&&u.add(d)}),u.forEach(d=>{h=Pi(o,d,u,l.insertions,e.ignoreRemoteMapChanges,e)!==null||h});for(let d=a.length-1;d>=0;d--){let f=a[d];e.deleteFilter(f)&&(f.delete(o),h=!0)}e.currStackItem=h?l:null}o.changed.forEach((c,l)=>{c.has(null)&&l._searchMarker&&(l._searchMarker.length=0)}),r=o},e),e.currStackItem!=null){let o=r.changedParentTypes;e.emit("stack-item-popped",[{stackItem:e.currStackItem,type:n,changedParentTypes:o,origin:e},e]),e.currStackItem=null}return e.currStackItem},Lr=class extends $t{constructor(t,{captureTimeout:n=500,captureTransaction:r=l=>!0,deleteFilter:s=()=>!0,trackedOrigins:i=new Set([null]),ignoreRemoteMapChanges:o=!1,doc:c=it(t)?t[0].doc:t.doc}={}){super(),this.scope=[],this.doc=c,this.addToScope(t),this.deleteFilter=s,i.add(this),this.trackedOrigins=i,this.captureTransaction=r,this.undoStack=[],this.redoStack=[],this.undoing=!1,this.redoing=!1,this.currStackItem=null,this.lastChange=0,this.ignoreRemoteMapChanges=o,this.captureTimeout=n,this.afterTransactionHandler=l=>{if(!this.captureTransaction(l)||!this.scope.some(m=>l.changedParentTypes.has(m))||!this.trackedOrigins.has(l.origin)&&(!l.origin||!this.trackedOrigins.has(l.origin.constructor)))return;let u=this.undoing,a=this.redoing,h=u?this.redoStack:this.undoStack;u?this.stopCapturing():a||this.clear(!1,!0);let d=new mt;l.afterState.forEach((m,x)=>{let q=l.beforeState.get(x)||0,Qr=m-q;Qr>0&&Le(d,x,q,Qr)});let f=rn(),p=!1;if(this.lastChange>0&&f-this.lastChange<this.captureTimeout&&h.length>0&&!u&&!a){let m=h[h.length-1];m.deletions=ie([m.deletions,l.deleteSet]),m.insertions=ie([m.insertions,d])}else h.push(new Nr(l.deleteSet,d)),p=!0;!u&&!a&&(this.lastChange=f),It(l,l.deleteSet,m=>{m instanceof S&&this.scope.some(x=>Be(x,m))&&Zr(m,!0)});let b=[{stackItem:h[h.length-1],origin:l.origin,type:u?"redo":"undo",changedParentTypes:l.changedParentTypes},this];p?this.emit("stack-item-added",b):this.emit("stack-item-updated",b)},this.doc.on("afterTransaction",this.afterTransactionHandler),this.doc.on("destroy",()=>{this.destroy()})}addToScope(t){t=it(t)?t:[t],t.forEach(n=>{this.scope.every(r=>r!==n)&&(n.doc!==this.doc&&qs("[yjs#509] Not same Y.Doc"),this.scope.push(n))})}addTrackedOrigin(t){this.trackedOrigins.add(t)}removeTrackedOrigin(t){this.trackedOrigins.delete(t)}clear(t=!0,n=!0){(t&&this.canUndo()||n&&this.canRedo())&&this.doc.transact(r=>{t&&(this.undoStack.forEach(s=>ri(r,this,s)),this.undoStack=[]),n&&(this.redoStack.forEach(s=>ri(r,this,s)),this.redoStack=[]),this.emit("stack-cleared",[{undoStackCleared:t,redoStackCleared:n}])})}stopCapturing(){this.lastChange=0}undo(){this.undoing=!0;let t;try{t=si(this,this.undoStack,"undo")}finally{this.undoing=!1}return t}redo(){this.redoing=!0;let t;try{t=si(this,this.redoStack,"redo")}finally{this.redoing=!1}return t}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}destroy(){this.trackedOrigins.delete(this),this.doc.off("afterTransaction",this.afterTransactionHandler),super.destroy()}};function*al(e){let t=y(e.restDecoder);for(let n=0;n<t;n++){let r=y(e.restDecoder),s=e.readClient(),i=y(e.restDecoder);for(let o=0;o<r;o++){let c=e.readInfo();if(c===10){let l=y(e.restDecoder);yield new O(w(s,i),l),i+=l}else if(31&c){let l=(c&192)===0,u=new S(w(s,i),null,(c&128)===128?e.readLeftID():null,null,(c&64)===64?e.readRightID():null,l?e.readParentInfo()?e.readString():e.readLeftID():null,l&&(c&32)===32?e.readString():null,Ki(e,c));yield u,i+=u.length}else{let l=e.readLen();yield new N(w(s,i),l),i+=l}}}}var rt=class{constructor(t,n){this.gen=al(t),this.curr=null,this.done=!1,this.filterSkips=n,this.next()}next(){do this.curr=this.gen.next().value||null;while(this.filterSkips&&this.curr!==null&&this.curr.constructor===O);return this.curr}},hl=e=>Si(e,j),Si=(e,t=R)=>{let n=[],r=new t(V(e)),s=new rt(r,!1);for(let o=s.curr;o!==null;o=s.next())n.push(o);kn("Structs: ",n);let i=lt(r);kn("DeleteSet: ",i)},ul=e=>_i(e,j),_i=(e,t=R)=>{let n=[],r=new t(V(e)),s=new rt(r,!1);for(let i=s.curr;i!==null;i=s.next())n.push(i);return{structs:n,ds:lt(r)}},Re=class{constructor(t){this.currClient=0,this.startClock=0,this.written=0,this.encoder=t,this.clientStructs=[]}},Ei=e=>$e(e,j,nt),Ui=(e,t=oe,n=R)=>{let r=new t,s=new rt(new n(V(e)),!1),i=s.curr;if(i!==null){let o=0,c=i.id.client,l=i.id.clock!==0,u=l?0:i.id.clock+i.length;for(;i!==null;i=s.next())c!==i.id.client&&(u!==0&&(o++,g(r.restEncoder,c),g(r.restEncoder,u)),c=i.id.client,u=0,l=i.id.clock!==0),i.constructor===O&&(l=!0),l||(u=i.id.clock+i.length);u!==0&&(o++,g(r.restEncoder,c),g(r.restEncoder,u));let a=St();return g(a,o),hs(a,r.restEncoder),r.restEncoder=a,r.toUint8Array()}else return g(r.restEncoder,0),r.toUint8Array()},dl=e=>Ui(e,wt,j),Ci=(e,t=R)=>{let n=new Map,r=new Map,s=new rt(new t(V(e)),!1),i=s.curr;if(i!==null){let o=i.id.client,c=i.id.clock;for(n.set(o,c);i!==null;i=s.next())o!==i.id.client&&(r.set(o,c),n.set(i.id.client,i.id.clock),o=i.id.client),c=i.id.clock+i.length;r.set(o,c)}return{from:n,to:r}},fl=e=>Ci(e,j),pl=(e,t)=>{if(e.constructor===N){let{client:n,clock:r}=e.id;return new N(w(n,r+t),e.length-t)}else if(e.constructor===O){let{client:n,clock:r}=e.id;return new O(w(n,r+t),e.length-t)}else{let n=e,{client:r,clock:s}=n.id;return new S(w(r,s+t),null,w(r,s+t-1),null,n.rightOrigin,n.parent,n.parentSub,n.content.splice(t))}},$e=(e,t=R,n=J)=>{if(e.length===1)return e[0];let r=e.map(a=>new t(V(a))),s=r.map(a=>new rt(a,!0)),i=null,o=new n,c=new Re(o);for(;s=s.filter(d=>d.curr!==null),s.sort((d,f)=>{if(d.curr.id.client===f.curr.id.client){let p=d.curr.id.clock-f.curr.id.clock;return p===0?d.curr.constructor===f.curr.constructor?0:d.curr.constructor===O?1:-1:p}else return f.curr.id.client-d.curr.id.client}),s.length!==0;){let a=s[0],h=a.curr.id.client;if(i!==null){let d=a.curr,f=!1;for(;d!==null&&d.id.clock+d.length<=i.struct.id.clock+i.struct.length&&d.id.client>=i.struct.id.client;)d=a.next(),f=!0;if(d===null||d.id.client!==h||f&&d.id.clock>i.struct.id.clock+i.struct.length)continue;if(h!==i.struct.id.client)pt(c,i.struct,i.offset),i={struct:d,offset:0},a.next();else if(i.struct.id.clock+i.struct.length<d.id.clock)if(i.struct.constructor===O)i.struct.length=d.id.clock+d.length-i.struct.id.clock;else{pt(c,i.struct,i.offset);let p=d.id.clock-i.struct.id.clock-i.struct.length;i={struct:new O(w(h,i.struct.id.clock+i.struct.length),p),offset:0}}else{let p=i.struct.id.clock+i.struct.length-d.id.clock;p>0&&(i.struct.constructor===O?i.struct.length-=p:d=pl(d,p)),i.struct.mergeWith(d)||(pt(c,i.struct,i.offset),i={struct:d,offset:0},a.next())}}else i={struct:a.curr,offset:0},a.next();for(let d=a.curr;d!==null&&d.id.client===h&&d.id.clock===i.struct.id.clock+i.struct.length&&d.constructor!==O;d=a.next())pt(c,i.struct,i.offset),i={struct:d,offset:0}}i!==null&&(pt(c,i.struct,i.offset),i=null),Pr(c);let l=r.map(a=>lt(a)),u=ie(l);return et(o,u),o.toUint8Array()},Xr=(e,t,n=R,r=J)=>{let s=Gr(t),i=new r,o=new Re(i),c=new n(V(e)),l=new rt(c,!1);for(;l.curr;){let a=l.curr,h=a.id.client,d=s.get(h)||0;if(l.curr.constructor===O){l.next();continue}if(a.id.clock+a.length>d)for(pt(o,a,ot(d-a.id.clock,0)),l.next();l.curr&&l.curr.id.client===h;)pt(o,l.curr,0),l.next();else for(;l.curr&&l.curr.id.client===h&&l.curr.id.clock+l.curr.length<=d;)l.next()}Pr(o);let u=lt(c);return et(i,u),i.toUint8Array()},gl=(e,t)=>Xr(e,t,j,nt),Ai=e=>{e.written>0&&(e.clientStructs.push({written:e.written,restEncoder:G(e.encoder.restEncoder)}),e.encoder.restEncoder=St(),e.written=0)},pt=(e,t,n)=>{e.written>0&&e.currClient!==t.id.client&&Ai(e),e.written===0&&(e.currClient=t.id.client,e.encoder.writeClient(t.id.client),g(e.encoder.restEncoder,t.id.clock+n)),t.write(e.encoder,n),e.written++},Pr=e=>{Ai(e);let t=e.encoder.restEncoder;g(t,e.clientStructs.length);for(let n=0;n<e.clientStructs.length;n++){let r=e.clientStructs[n];g(t,r.written),Xt(t,r.restEncoder)}},qn=(e,t,n,r)=>{let s=new n(V(e)),i=new rt(s,!1),o=new r,c=new Re(o);for(let u=i.curr;u!==null;u=i.next())pt(c,t(u),0);Pr(c);let l=lt(s);return et(o,l),o.toUint8Array()},Ii=({formatting:e=!0,subdocs:t=!0,yxml:n=!0}={})=>{let r=0,s=A(),i=A(),o=A(),c=A();return c.set(null,null),l=>{switch(l.constructor){case N:case O:return l;case S:{let u=l,a=u.content;switch(a.constructor){case he:break;case K:{if(n){let h=a.type;h instanceof Lt&&(h.nodeName=L(i,h.nodeName,()=>"node-"+r)),h instanceof Ge&&(h.hookName=L(i,h.hookName,()=>"hook-"+r))}break}case yt:{let h=a;h.arr=h.arr.map(()=>r);break}case Bt:{let h=a;h.content=new Uint8Array([r]);break}case Mt:{let h=a;t&&(h.opts={},h.doc.guid=r+"");break}case at:{let h=a;h.embed={};break}case E:{let h=a;e&&(h.key=L(o,h.key,()=>r+""),h.value=L(c,h.value,()=>({i:r})));break}case ze:{let h=a;h.arr=h.arr.map(()=>r);break}case Y:{let h=a;h.str=Qe(r%10+"",h.str.length);break}default:D()}return u.parentSub&&(u.parentSub=L(s,u.parentSub,()=>r+"")),r++,l}default:D()}}},ml=(e,t)=>qn(e,Ii(t),j,nt),wl=(e,t)=>qn(e,Ii(t),R,J),yl=e=>qn(e,lr,j,J),Ti=e=>qn(e,lr,R,nt),ii="You must not compute changes after the event-handler fired.",vt=class{constructor(t,n){this.target=t,this.currentTarget=t,this.transaction=n,this._changes=null,this._keys=null,this._delta=null,this._path=null}get path(){return this._path||(this._path=xl(this.currentTarget,this.target))}deletes(t){return Rt(this.transaction.deleteSet,t.id)}get keys(){if(this._keys===null){if(this.transaction.doc._transactionCleanups.length===0)throw z(ii);let t=new Map,n=this.target;this.transaction.changed.get(n).forEach(s=>{if(s!==null){let i=n._map.get(s),o,c;if(this.adds(i)){let l=i.left;for(;l!==null&&this.adds(l);)l=l.left;if(this.deletes(i))if(l!==null&&this.deletes(l))o="delete",c=Ke(l.content.getContent());else return;else l!==null&&this.deletes(l)?(o="update",c=Ke(l.content.getContent())):(o="add",c=void 0)}else if(this.deletes(i))o="delete",c=Ke(i.content.getContent());else return;t.set(s,{action:o,oldValue:c})}}),this._keys=t}return this._keys}get delta(){return this.changes.delta}adds(t){return t.id.clock>=(this.transaction.beforeState.get(t.id.client)||0)}get changes(){let t=this._changes;if(t===null){if(this.transaction.doc._transactionCleanups.length===0)throw z(ii);let n=this.target,r=st(),s=st(),i=[];if(t={added:r,deleted:s,delta:i,keys:this.keys},this.transaction.changed.get(n).has(null)){let c=null,l=()=>{c&&i.push(c)};for(let u=n._start;u!==null;u=u.right)u.deleted?this.deletes(u)&&!this.adds(u)&&((c===null||c.delete===void 0)&&(l(),c={delete:0}),c.delete+=u.length,s.add(u)):this.adds(u)?((c===null||c.insert===void 0)&&(l(),c={insert:[]}),c.insert=c.insert.concat(u.content.getContent()),r.add(u)):((c===null||c.retain===void 0)&&(l(),c={retain:0}),c.retain+=u.length);c!==null&&c.retain===void 0&&l()}this._changes=t}return t}},xl=(e,t)=>{let n=[];for(;t._item!==null&&t!==e;){if(t._item.parentSub!==null)n.unshift(t._item.parentSub);else{let r=0,s=t._item.parent._start;for(;s!==t._item&&s!==null;)s.deleted||r++,s=s.right;n.unshift(r)}t=t._item.parent}return n},Di=80,Kr=0,Br=class{constructor(t,n){t.marker=!0,this.p=t,this.index=n,this.timestamp=Kr++}},bl=e=>{e.timestamp=Kr++},vi=(e,t,n)=>{e.p.marker=!1,e.p=t,t.marker=!0,e.index=n,e.timestamp=Kr++},kl=(e,t,n)=>{if(e.length>=Di){let r=e.reduce((s,i)=>s.timestamp<i.timestamp?s:i);return vi(r,t,n),r}else{let r=new Br(t,n);return e.push(r),r}},Gn=(e,t)=>{if(e._start===null||t===0||e._searchMarker===null)return null;let n=e._searchMarker.length===0?null:e._searchMarker.reduce((i,o)=>xt(t-i.index)<xt(t-o.index)?i:o),r=e._start,s=0;for(n!==null&&(r=n.p,s=n.index,bl(n));r.right!==null&&s<t;){if(!r.deleted&&r.countable){if(t<s+r.length)break;s+=r.length}r=r.right}for(;r.left!==null&&s>t;)r=r.left,!r.deleted&&r.countable&&(s-=r.length);for(;r.left!==null&&r.left.id.client===r.id.client&&r.left.id.clock+r.left.length===r.id.clock;)r=r.left,!r.deleted&&r.countable&&(s-=r.length);return n!==null&&xt(n.index-s)<r.parent.length/Di?(vi(n,r,s),n):kl(e._searchMarker,r,s)},Fe=(e,t,n)=>{for(let r=e.length-1;r>=0;r--){let s=e[r];if(n>0){let i=s.p;for(i.marker=!1;i&&(i.deleted||!i.countable);)i=i.left,i&&!i.deleted&&i.countable&&(s.index-=i.length);if(i===null||i.marker===!0){e.splice(r,1);continue}s.p=i,i.marker=!0}(t<s.index||n>0&&t===s.index)&&(s.index=ot(t,s.index+n))}},Sl=e=>{let t=e._start,n=[];for(;t;)n.push(t),t=t.right;return n},zn=(e,t,n)=>{let r=e,s=t.changedParentTypes;for(;L(s,e,()=>[]).push(n),e._item!==null;)e=e._item.parent;pi(r._eH,n,t)},C=class{constructor(){this._item=null,this._map=new Map,this._start=null,this.doc=null,this._length=0,this._eH=Ks(),this._dEH=Ks(),this._searchMarker=null}get parent(){return this._item?this._item.parent:null}_integrate(t,n){this.doc=t,this._item=n}_copy(){throw H()}clone(){throw H()}_write(t){}get _first(){let t=this._start;for(;t!==null&&t.deleted;)t=t.right;return t}_callObserver(t,n){!t.local&&this._searchMarker&&(this._searchMarker.length=0)}observe(t){Ys(this._eH,t)}observeDeep(t){Ys(this._dEH,t)}unobserve(t){Ws(this._eH,t)}unobserveDeep(t){Ws(this._dEH,t)}toJSON(){}},Vi=(e,t,n)=>{t<0&&(t=e._length+t),n<0&&(n=e._length+n);let r=n-t,s=[],i=e._start;for(;i!==null&&r>0;){if(i.countable&&!i.deleted){let o=i.content.getContent();if(o.length<=t)t-=o.length;else{for(let c=t;c<o.length&&r>0;c++)s.push(o[c]),r--;t=0}}i=i.right}return s},Oi=e=>{let t=[],n=e._start;for(;n!==null;){if(n.countable&&!n.deleted){let r=n.content.getContent();for(let s=0;s<r.length;s++)t.push(r[s])}n=n.right}return t},_l=(e,t)=>{let n=[],r=e._start;for(;r!==null;){if(r.countable&&ft(r,t)){let s=r.content.getContent();for(let i=0;i<s.length;i++)n.push(s[i])}r=r.right}return n},je=(e,t)=>{let n=0,r=e._start;for(;r!==null;){if(r.countable&&!r.deleted){let s=r.content.getContent();for(let i=0;i<s.length;i++)t(s[i],n++,e)}r=r.right}},Ni=(e,t)=>{let n=[];return je(e,(r,s)=>{n.push(t(r,s,e))}),n},El=e=>{let t=e._start,n=null,r=0;return{[Symbol.iterator](){return this},next:()=>{if(n===null){for(;t!==null&&t.deleted;)t=t.right;if(t===null)return{done:!0,value:void 0};n=t.content.getContent(),r=0,t=t.right}let s=n[r++];return n.length<=r&&(n=null),{done:!1,value:s}}}},Li=(e,t)=>{let n=Gn(e,t),r=e._start;for(n!==null&&(r=n.p,t-=n.index);r!==null;r=r.right)if(!r.deleted&&r.countable){if(t<r.length)return r.content.getContent()[t];t-=r.length}},Vn=(e,t,n,r)=>{let s=n,i=e.doc,o=i.clientID,c=i.store,l=n===null?t._start:n.right,u=[],a=()=>{u.length>0&&(s=new S(w(o,_(c,o)),s,s&&s.lastId,l,l&&l.id,t,null,new yt(u)),s.integrate(e,0),u=[])};r.forEach(h=>{if(h===null)u.push(h);else switch(h.constructor){case Number:case Object:case Boolean:case Array:case String:u.push(h);break;default:switch(a(),h.constructor){case Uint8Array:case ArrayBuffer:s=new S(w(o,_(c,o)),s,s&&s.lastId,l,l&&l.id,t,null,new Bt(new Uint8Array(h))),s.integrate(e,0);break;case Tt:s=new S(w(o,_(c,o)),s,s&&s.lastId,l,l&&l.id,t,null,new Mt(h)),s.integrate(e,0);break;default:if(h instanceof C)s=new S(w(o,_(c,o)),s,s&&s.lastId,l,l&&l.id,t,null,new K(h)),s.integrate(e,0);else throw new Error("Unexpected content type in insert operation")}}}),a()},Bi=()=>z("Length exceeded!"),Mi=(e,t,n,r)=>{if(n>t._length)throw Bi();if(n===0)return t._searchMarker&&Fe(t._searchMarker,n,r.length),Vn(e,t,null,r);let s=n,i=Gn(t,n),o=t._start;for(i!==null&&(o=i.p,n-=i.index,n===0&&(o=o.prev,n+=o&&o.countable&&!o.deleted?o.length:0));o!==null;o=o.right)if(!o.deleted&&o.countable){if(n<=o.length){n<o.length&&M(e,w(o.id.client,o.id.clock+n));break}n-=o.length}return t._searchMarker&&Fe(t._searchMarker,s,r.length),Vn(e,t,o,r)},Ul=(e,t,n)=>{let s=(t._searchMarker||[]).reduce((i,o)=>o.index>i.index?o:i,{index:0,p:t._start}).p;if(s)for(;s.right;)s=s.right;return Vn(e,t,s,n)},Ri=(e,t,n,r)=>{if(r===0)return;let s=n,i=r,o=Gn(t,n),c=t._start;for(o!==null&&(c=o.p,n-=o.index);c!==null&&n>0;c=c.right)!c.deleted&&c.countable&&(n<c.length&&M(e,w(c.id.client,c.id.clock+n)),n-=c.length);for(;r>0&&c!==null;)c.deleted||(r<c.length&&M(e,w(c.id.client,c.id.clock+r)),c.delete(e),r-=c.length),c=c.right;if(r>0)throw Bi();t._searchMarker&&Fe(t._searchMarker,s,-i+r)},On=(e,t,n)=>{let r=t._map.get(n);r!==void 0&&r.delete(e)},Yr=(e,t,n,r)=>{let s=t._map.get(n)||null,i=e.doc,o=i.clientID,c;if(r==null)c=new yt([r]);else switch(r.constructor){case Number:case Object:case Boolean:case Array:case String:c=new yt([r]);break;case Uint8Array:c=new Bt(r);break;case Tt:c=new Mt(r);break;default:if(r instanceof C)c=new K(r);else throw new Error("Unexpected content type")}new S(w(o,_(i.store,o)),s,s&&s.lastId,null,null,t,n,c).integrate(e,0)},Wr=(e,t)=>{let n=e._map.get(t);return n!==void 0&&!n.deleted?n.content.getContent()[n.length-1]:void 0},$i=e=>{let t={};return e._map.forEach((n,r)=>{n.deleted||(t[r]=n.content.getContent()[n.length-1])}),t},Fi=(e,t)=>{let n=e._map.get(t);return n!==void 0&&!n.deleted},Cl=(e,t,n)=>{let r=e._map.get(t)||null;for(;r!==null&&(!n.sv.has(r.id.client)||r.id.clock>=(n.sv.get(r.id.client)||0));)r=r.left;return r!==null&&ft(r,n)?r.content.getContent()[r.length-1]:void 0},ji=(e,t)=>{let n={};return e._map.forEach((r,s)=>{let i=r;for(;i!==null&&(!t.sv.has(i.id.client)||i.id.clock>=(t.sv.get(i.id.client)||0));)i=i.left;i!==null&&ft(i,t)&&(n[s]=i.content.getContent()[i.length-1])}),n},En=e=>Hs(e.entries(),t=>!t[1].deleted),Nn=class extends vt{constructor(t,n){super(t,n),this._transaction=n}},Vt=class e extends C{constructor(){super(),this._prelimContent=[],this._searchMarker=[]}static from(t){let n=new e;return n.push(t),n}_integrate(t,n){super._integrate(t,n),this.insert(0,this._prelimContent),this._prelimContent=null}_copy(){return new e}clone(){let t=new e;return t.insert(0,this.toArray().map(n=>n instanceof C?n.clone():n)),t}get length(){return this._prelimContent===null?this._length:this._prelimContent.length}_callObserver(t,n){super._callObserver(t,n),zn(this,t,new Nn(this,t))}insert(t,n){this.doc!==null?k(this.doc,r=>{Mi(r,this,t,n)}):this._prelimContent.splice(t,0,...n)}push(t){this.doc!==null?k(this.doc,n=>{Ul(n,this,t)}):this._prelimContent.push(...t)}unshift(t){this.insert(0,t)}delete(t,n=1){this.doc!==null?k(this.doc,r=>{Ri(r,this,t,n)}):this._prelimContent.splice(t,n)}get(t){return Li(this,t)}toArray(){return Oi(this)}slice(t=0,n=this.length){return Vi(this,t,n)}toJSON(){return this.map(t=>t instanceof C?t.toJSON():t)}map(t){return Ni(this,t)}forEach(t){je(this,t)}[Symbol.iterator](){return El(this)}_write(t){t.writeTypeRef(Jl)}},Al=e=>new Vt,Ln=class extends vt{constructor(t,n,r){super(t,n),this.keysChanged=r}},Ot=class e extends C{constructor(t){super(),this._prelimContent=null,t===void 0?this._prelimContent=new Map:this._prelimContent=new Map(t)}_integrate(t,n){super._integrate(t,n),this._prelimContent.forEach((r,s)=>{this.set(s,r)}),this._prelimContent=null}_copy(){return new e}clone(){let t=new e;return this.forEach((n,r)=>{t.set(r,n instanceof C?n.clone():n)}),t}_callObserver(t,n){zn(this,t,new Ln(this,t,n))}toJSON(){let t={};return this._map.forEach((n,r)=>{if(!n.deleted){let s=n.content.getContent()[n.length-1];t[r]=s instanceof C?s.toJSON():s}}),t}get size(){return[...En(this._map)].length}keys(){return Sn(En(this._map),t=>t[0])}values(){return Sn(En(this._map),t=>t[1].content.getContent()[t[1].length-1])}entries(){return Sn(En(this._map),t=>[t[0],t[1].content.getContent()[t[1].length-1]])}forEach(t){this._map.forEach((n,r)=>{n.deleted||t(n.content.getContent()[n.length-1],r,this)})}[Symbol.iterator](){return this.entries()}delete(t){this.doc!==null?k(this.doc,n=>{On(n,this,t)}):this._prelimContent.delete(t)}set(t,n){return this.doc!==null?k(this.doc,r=>{Yr(r,this,t,n)}):this._prelimContent.set(t,n),n}get(t){return Wr(this,t)}has(t){return Fi(this,t)}clear(){this.doc!==null?k(this.doc,t=>{this.forEach(function(n,r,s){On(t,s,r)})}):this._prelimContent.clear()}_write(t){t.writeTypeRef(Xl)}},Il=e=>new Ot,gt=(e,t)=>e===t||typeof e=="object"&&typeof t=="object"&&e&&t&&or(e,t),qe=class{constructor(t,n,r,s){this.left=t,this.right=n,this.index=r,this.currentAttributes=s}forward(){switch(this.right===null&&D(),this.right.content.constructor){case E:this.right.deleted||ue(this.currentAttributes,this.right.content);break;default:this.right.deleted||(this.index+=this.right.length);break}this.left=this.right,this.right=this.right.right}},oi=(e,t,n)=>{for(;t.right!==null&&n>0;){switch(t.right.content.constructor){case E:t.right.deleted||ue(t.currentAttributes,t.right.content);break;default:t.right.deleted||(n<t.right.length&&M(e,w(t.right.id.client,t.right.id.clock+n)),t.index+=t.right.length,n-=t.right.length);break}t.left=t.right,t.right=t.right.right}return t},Un=(e,t,n,r)=>{let s=new Map,i=r?Gn(t,n):null;if(i){let o=new qe(i.p.left,i.p,i.index,s);return oi(e,o,n-i.index)}else{let o=new qe(null,t._start,0,s);return oi(e,o,n)}},qi=(e,t,n,r)=>{for(;n.right!==null&&(n.right.deleted===!0||n.right.content.constructor===E&>(r.get(n.right.content.key),n.right.content.value));)n.right.deleted||r.delete(n.right.content.key),n.forward();let s=e.doc,i=s.clientID;r.forEach((o,c)=>{let l=n.left,u=n.right,a=new S(w(i,_(s.store,i)),l,l&&l.lastId,u,u&&u.id,t,null,new E(c,o));a.integrate(e,0),n.right=a,n.forward()})},ue=(e,t)=>{let{key:n,value:r}=t;r===null?e.delete(n):e.set(n,r)},Gi=(e,t)=>{var n;for(;e.right!==null;){if(!(e.right.deleted||e.right.content.constructor===E&>((n=t[e.right.content.key])!=null?n:null,e.right.content.value)))break;e.forward()}},zi=(e,t,n,r)=>{var c;let s=e.doc,i=s.clientID,o=new Map;for(let l in r){let u=r[l],a=(c=n.currentAttributes.get(l))!=null?c:null;if(!gt(a,u)){o.set(l,a);let{left:h,right:d}=n;n.right=new S(w(i,_(s.store,i)),h,h&&h.lastId,d,d&&d.id,t,null,new E(l,u)),n.right.integrate(e,0),n.forward()}}return o},Ir=(e,t,n,r,s)=>{n.currentAttributes.forEach((d,f)=>{s[f]===void 0&&(s[f]=null)});let i=e.doc,o=i.clientID;Gi(n,s);let c=zi(e,t,n,s),l=r.constructor===String?new Y(r):r instanceof C?new K(r):new at(r),{left:u,right:a,index:h}=n;t._searchMarker&&Fe(t._searchMarker,n.index,l.getLength()),a=new S(w(o,_(i.store,o)),u,u&&u.lastId,a,a&&a.id,t,null,l),a.integrate(e,0),n.right=a,n.index=h,n.forward(),qi(e,t,n,c)},ci=(e,t,n,r,s)=>{let i=e.doc,o=i.clientID;Gi(n,s);let c=zi(e,t,n,s);t:for(;n.right!==null&&(r>0||c.size>0&&(n.right.deleted||n.right.content.constructor===E));){if(!n.right.deleted)switch(n.right.content.constructor){case E:{let{key:l,value:u}=n.right.content,a=s[l];if(a!==void 0){if(gt(a,u))c.delete(l);else{if(r===0)break t;c.set(l,u)}n.right.delete(e)}else n.currentAttributes.set(l,u);break}default:r<n.right.length&&M(e,w(n.right.id.client,n.right.id.clock+r)),r-=n.right.length;break}n.forward()}if(r>0){let l="";for(;r>0;r--)l+=`
|
|
11305
|
+
`;n.right=new S(w(o,_(i.store,o)),n.left,n.left&&n.left.lastId,n.right,n.right&&n.right.id,t,null,new Y(l)),n.right.integrate(e,0),n.forward()}qi(e,t,n,c)},Hi=(e,t,n,r,s)=>{var u,a;let i=t,o=A();for(;i&&(!i.countable||i.deleted);){if(!i.deleted&&i.content.constructor===E){let h=i.content;o.set(h.key,h)}i=i.right}let c=0,l=!1;for(;t!==i;){if(n===t&&(l=!0),!t.deleted){let h=t.content;switch(h.constructor){case E:{let{key:d,value:f}=h,p=(u=r.get(d))!=null?u:null;(o.get(d)!==h||p===f)&&(t.delete(e),c++,!l&&((a=s.get(d))!=null?a:null)===f&&p!==f&&(p===null?s.delete(d):s.set(d,p))),!l&&!t.deleted&&ue(s,h);break}}}t=t.right}return c},Tl=(e,t)=>{for(;t&&t.right&&(t.right.deleted||!t.right.countable);)t=t.right;let n=new Set;for(;t&&(t.deleted||!t.countable);){if(!t.deleted&&t.content.constructor===E){let r=t.content.key;n.has(r)?t.delete(e):n.add(r)}t=t.left}},Ji=e=>{let t=0;return k(e.doc,n=>{let r=e._start,s=e._start,i=A(),o=Pe(i);for(;s;){if(s.deleted===!1)switch(s.content.constructor){case E:ue(o,s.content);break;default:t+=Hi(n,r,s,i,o),i=Pe(o),r=s;break}s=s.right}}),t},Dl=e=>{let t=new Set,n=e.doc;for(let[r,s]of e.afterState.entries()){let i=e.beforeState.get(r)||0;s!==i&&yi(e,n.store.clients.get(r),i,s,o=>{!o.deleted&&o.content.constructor===E&&o.constructor!==N&&t.add(o.parent)})}k(n,r=>{It(e,e.deleteSet,s=>{if(s instanceof N||!s.parent._hasFormatting||t.has(s.parent))return;let i=s.parent;s.content.constructor===E?t.add(i):Tl(r,s)});for(let s of t)Ji(s)})},li=(e,t,n)=>{let r=n,s=Pe(t.currentAttributes),i=t.right;for(;n>0&&t.right!==null;){if(t.right.deleted===!1)switch(t.right.content.constructor){case K:case at:case Y:n<t.right.length&&M(e,w(t.right.id.client,t.right.id.clock+n)),n-=t.right.length,t.right.delete(e);break}t.forward()}i&&Hi(e,i,t.right,s,t.currentAttributes);let o=(t.left||t.right).parent;return o._searchMarker&&Fe(o._searchMarker,t.index,-r+n),t},Bn=class extends vt{constructor(t,n,r){super(t,n),this.childListChanged=!1,this.keysChanged=new Set,r.forEach(s=>{s===null?this.childListChanged=!0:this.keysChanged.add(s)})}get changes(){if(this._changes===null){let t={keys:this.keys,delta:this.delta,added:new Set,deleted:new Set};this._changes=t}return this._changes}get delta(){if(this._delta===null){let t=this.target.doc,n=[];k(t,r=>{var f,p,b;let s=new Map,i=new Map,o=this.target._start,c=null,l={},u="",a=0,h=0,d=()=>{if(c!==null){let m=null;switch(c){case"delete":h>0&&(m={delete:h}),h=0;break;case"insert":(typeof u=="object"||u.length>0)&&(m={insert:u},s.size>0&&(m.attributes={},s.forEach((x,q)=>{x!==null&&(m.attributes[q]=x)}))),u="";break;case"retain":a>0&&(m={retain:a},bs(l)||(m.attributes=ys({},l))),a=0;break}m&&n.push(m),c=null}};for(;o!==null;){switch(o.content.constructor){case K:case at:this.adds(o)?this.deletes(o)||(d(),c="insert",u=o.content.getContent()[0],d()):this.deletes(o)?(c!=="delete"&&(d(),c="delete"),h+=1):o.deleted||(c!=="retain"&&(d(),c="retain"),a+=1);break;case Y:this.adds(o)?this.deletes(o)||(c!=="insert"&&(d(),c="insert"),u+=o.content.str):this.deletes(o)?(c!=="delete"&&(d(),c="delete"),h+=o.length):o.deleted||(c!=="retain"&&(d(),c="retain"),a+=o.length);break;case E:{let{key:m,value:x}=o.content;if(this.adds(o)){if(!this.deletes(o)){let q=(f=s.get(m))!=null?f:null;gt(q,x)?x!==null&&o.delete(r):(c==="retain"&&d(),gt(x,(p=i.get(m))!=null?p:null)?delete l[m]:l[m]=x)}}else if(this.deletes(o)){i.set(m,x);let q=(b=s.get(m))!=null?b:null;gt(q,x)||(c==="retain"&&d(),l[m]=q)}else if(!o.deleted){i.set(m,x);let q=l[m];q!==void 0&&(gt(q,x)?q!==null&&o.delete(r):(c==="retain"&&d(),x===null?delete l[m]:l[m]=x))}o.deleted||(c==="insert"&&d(),ue(s,o.content));break}}o=o.right}for(d();n.length>0;){let m=n[n.length-1];if(m.retain!==void 0&&m.attributes===void 0)n.pop();else break}}),this._delta=n}return this._delta}},le=class e extends C{constructor(t){super(),this._pending=t!==void 0?[()=>this.insert(0,t)]:[],this._searchMarker=[],this._hasFormatting=!1}get length(){return this._length}_integrate(t,n){super._integrate(t,n);try{this._pending.forEach(r=>r())}catch(r){console.error(r)}this._pending=null}_copy(){return new e}clone(){let t=new e;return t.applyDelta(this.toDelta()),t}_callObserver(t,n){super._callObserver(t,n);let r=new Bn(this,t,n);zn(this,t,r),!t.local&&this._hasFormatting&&(t._needFormattingCleanup=!0)}toString(){let t="",n=this._start;for(;n!==null;)!n.deleted&&n.countable&&n.content.constructor===Y&&(t+=n.content.str),n=n.right;return t}toJSON(){return this.toString()}applyDelta(t,{sanitize:n=!0}={}){this.doc!==null?k(this.doc,r=>{let s=new qe(null,this._start,0,new Map);for(let i=0;i<t.length;i++){let o=t[i];if(o.insert!==void 0){let c=!n&&typeof o.insert=="string"&&i===t.length-1&&s.right===null&&o.insert.slice(-1)===`
|
|
11306
|
+
`?o.insert.slice(0,-1):o.insert;(typeof c!="string"||c.length>0)&&Ir(r,this,s,c,o.attributes||{})}else o.retain!==void 0?ci(r,this,s,o.retain,o.attributes||{}):o.delete!==void 0&&li(r,s,o.delete)}}):this._pending.push(()=>this.applyDelta(t))}toDelta(t,n,r){let s=[],i=new Map,o=this.doc,c="",l=this._start;function u(){if(c.length>0){let h={},d=!1;i.forEach((p,b)=>{d=!0,h[b]=p});let f={insert:c};d&&(f.attributes=h),s.push(f),c=""}}let a=()=>{for(;l!==null;){if(ft(l,t)||n!==void 0&&ft(l,n))switch(l.content.constructor){case Y:{let h=i.get("ychange");t!==void 0&&!ft(l,t)?(h===void 0||h.user!==l.id.client||h.type!=="removed")&&(u(),i.set("ychange",r?r("removed",l.id):{type:"removed"})):n!==void 0&&!ft(l,n)?(h===void 0||h.user!==l.id.client||h.type!=="added")&&(u(),i.set("ychange",r?r("added",l.id):{type:"added"})):h!==void 0&&(u(),i.delete("ychange")),c+=l.content.str;break}case K:case at:{u();let h={insert:l.content.getContent()[0]};if(i.size>0){let d={};h.attributes=d,i.forEach((f,p)=>{d[p]=f})}s.push(h);break}case E:ft(l,t)&&(u(),ue(i,l.content));break}l=l.right}u()};return t||n?k(o,h=>{t&&Vr(h,t),n&&Vr(h,n),a()},"cleanup"):a(),s}insert(t,n,r){if(n.length<=0)return;let s=this.doc;s!==null?k(s,i=>{let o=Un(i,this,t,!r);r||(r={},o.currentAttributes.forEach((c,l)=>{r[l]=c})),Ir(i,this,o,n,r)}):this._pending.push(()=>this.insert(t,n,r))}insertEmbed(t,n,r){let s=this.doc;s!==null?k(s,i=>{let o=Un(i,this,t,!r);Ir(i,this,o,n,r||{})}):this._pending.push(()=>this.insertEmbed(t,n,r||{}))}delete(t,n){if(n===0)return;let r=this.doc;r!==null?k(r,s=>{li(s,Un(s,this,t,!0),n)}):this._pending.push(()=>this.delete(t,n))}format(t,n,r){if(n===0)return;let s=this.doc;s!==null?k(s,i=>{let o=Un(i,this,t,!1);o.right!==null&&ci(i,this,o,n,r)}):this._pending.push(()=>this.format(t,n,r))}removeAttribute(t){this.doc!==null?k(this.doc,n=>{On(n,this,t)}):this._pending.push(()=>this.removeAttribute(t))}setAttribute(t,n){this.doc!==null?k(this.doc,r=>{Yr(r,this,t,n)}):this._pending.push(()=>this.setAttribute(t,n))}getAttribute(t){return Wr(this,t)}getAttributes(){return $i(this)}_write(t){t.writeTypeRef(Pl)}},vl=e=>new le,Oe=class{constructor(t,n=()=>!0){this._filter=n,this._root=t,this._currentNode=t._start,this._firstCall=!0}[Symbol.iterator](){return this}next(){let t=this._currentNode,n=t&&t.content&&t.content.type;if(t!==null&&(!this._firstCall||t.deleted||!this._filter(n)))do if(n=t.content.type,!t.deleted&&(n.constructor===Lt||n.constructor===Nt)&&n._start!==null)t=n._start;else for(;t!==null;)if(t.right!==null){t=t.right;break}else t.parent===this._root?t=null:t=t.parent._item;while(t!==null&&(t.deleted||!this._filter(t.content.type)));return this._firstCall=!1,t===null?{value:void 0,done:!0}:(this._currentNode=t,{value:t.content.type,done:!1})}},Nt=class e extends C{constructor(){super(),this._prelimContent=[]}get firstChild(){let t=this._first;return t?t.content.getContent()[0]:null}_integrate(t,n){super._integrate(t,n),this.insert(0,this._prelimContent),this._prelimContent=null}_copy(){return new e}clone(){let t=new e;return t.insert(0,this.toArray().map(n=>n instanceof C?n.clone():n)),t}get length(){return this._prelimContent===null?this._length:this._prelimContent.length}createTreeWalker(t){return new Oe(this,t)}querySelector(t){t=t.toUpperCase();let r=new Oe(this,s=>s.nodeName&&s.nodeName.toUpperCase()===t).next();return r.done?null:r.value}querySelectorAll(t){return t=t.toUpperCase(),W(new Oe(this,n=>n.nodeName&&n.nodeName.toUpperCase()===t))}_callObserver(t,n){zn(this,t,new Mn(this,n,t))}toString(){return Ni(this,t=>t.toString()).join("")}toJSON(){return this.toString()}toDOM(t=document,n={},r){let s=t.createDocumentFragment();return r!==void 0&&r._createAssociation(s,this),je(this,i=>{s.insertBefore(i.toDOM(t,n,r),null)}),s}insert(t,n){this.doc!==null?k(this.doc,r=>{Mi(r,this,t,n)}):this._prelimContent.splice(t,0,...n)}insertAfter(t,n){if(this.doc!==null)k(this.doc,r=>{let s=t&&t instanceof C?t._item:t;Vn(r,this,s,n)});else{let r=this._prelimContent,s=t===null?0:r.findIndex(i=>i===t)+1;if(s===0&&t!==null)throw z("Reference item not found");r.splice(s,0,...n)}}delete(t,n=1){this.doc!==null?k(this.doc,r=>{Ri(r,this,t,n)}):this._prelimContent.splice(t,n)}toArray(){return Oi(this)}push(t){this.insert(this.length,t)}unshift(t){this.insert(0,t)}get(t){return Li(this,t)}slice(t=0,n=this.length){return Vi(this,t,n)}forEach(t){je(this,t)}_write(t){t.writeTypeRef(Yl)}},Vl=e=>new Nt,Lt=class e extends Nt{constructor(t="UNDEFINED"){super(),this.nodeName=t,this._prelimAttrs=new Map}get nextSibling(){let t=this._item?this._item.next:null;return t?t.content.type:null}get prevSibling(){let t=this._item?this._item.prev:null;return t?t.content.type:null}_integrate(t,n){super._integrate(t,n),this._prelimAttrs.forEach((r,s)=>{this.setAttribute(s,r)}),this._prelimAttrs=null}_copy(){return new e(this.nodeName)}clone(){let t=new e(this.nodeName),n=this.getAttributes();return xs(n,(r,s)=>{typeof r=="string"&&t.setAttribute(s,r)}),t.insert(0,this.toArray().map(r=>r instanceof C?r.clone():r)),t}toString(){let t=this.getAttributes(),n=[],r=[];for(let c in t)r.push(c);r.sort();let s=r.length;for(let c=0;c<s;c++){let l=r[c];n.push(l+'="'+t[l]+'"')}let i=this.nodeName.toLocaleLowerCase(),o=n.length>0?" "+n.join(" "):"";return`<${i}${o}>${super.toString()}</${i}>`}removeAttribute(t){this.doc!==null?k(this.doc,n=>{On(n,this,t)}):this._prelimAttrs.delete(t)}setAttribute(t,n){this.doc!==null?k(this.doc,r=>{Yr(r,this,t,n)}):this._prelimAttrs.set(t,n)}getAttribute(t){return Wr(this,t)}hasAttribute(t){return Fi(this,t)}getAttributes(t){return t?ji(this,t):$i(this)}toDOM(t=document,n={},r){let s=t.createElement(this.nodeName),i=this.getAttributes();for(let o in i){let c=i[o];typeof c=="string"&&s.setAttribute(o,c)}return je(this,o=>{s.appendChild(o.toDOM(t,n,r))}),r!==void 0&&r._createAssociation(s,this),s}_write(t){t.writeTypeRef(Kl),t.writeKey(this.nodeName)}},Ol=e=>new Lt(e.readKey()),Mn=class extends vt{constructor(t,n,r){super(t,r),this.childListChanged=!1,this.attributesChanged=new Set,n.forEach(s=>{s===null?this.childListChanged=!0:this.attributesChanged.add(s)})}},Ge=class e extends Ot{constructor(t){super(),this.hookName=t}_copy(){return new e(this.hookName)}clone(){let t=new e(this.hookName);return this.forEach((n,r)=>{t.set(r,n)}),t}toDOM(t=document,n={},r){let s=n[this.hookName],i;return s!==void 0?i=s.createDom(this):i=document.createElement(this.hookName),i.setAttribute("data-yjs-hook",this.hookName),r!==void 0&&r._createAssociation(i,this),i}_write(t){t.writeTypeRef(Wl),t.writeKey(this.hookName)}},Nl=e=>new Ge(e.readKey()),Rn=class e extends le{get nextSibling(){let t=this._item?this._item.next:null;return t?t.content.type:null}get prevSibling(){let t=this._item?this._item.prev:null;return t?t.content.type:null}_copy(){return new e}clone(){let t=new e;return t.applyDelta(this.toDelta()),t}toDOM(t=document,n,r){let s=t.createTextNode(this.toString());return r!==void 0&&r._createAssociation(s,this),s}toString(){return this.toDelta().map(t=>{let n=[];for(let s in t.attributes){let i=[];for(let o in t.attributes[s])i.push({key:o,value:t.attributes[s][o]});i.sort((o,c)=>o.key<c.key?-1:1),n.push({nodeName:s,attrs:i})}n.sort((s,i)=>s.nodeName<i.nodeName?-1:1);let r="";for(let s=0;s<n.length;s++){let i=n[s];r+=`<${i.nodeName}`;for(let o=0;o<i.attrs.length;o++){let c=i.attrs[o];r+=` ${c.key}="${c.value}"`}r+=">"}r+=t.insert;for(let s=n.length-1;s>=0;s--)r+=`</${n[s].nodeName}>`;return r}).join("")}toJSON(){return this.toString()}_write(t){t.writeTypeRef(Zl)}},Ll=e=>new Rn,ae=class{constructor(t,n){this.id=t,this.length=n}get deleted(){throw H()}mergeWith(t){return!1}write(t,n,r){throw H()}integrate(t,n){throw H()}},Bl=0,N=class extends ae{get deleted(){return!0}delete(){}mergeWith(t){return this.constructor!==t.constructor?!1:(this.length+=t.length,!0)}integrate(t,n){n>0&&(this.id.clock+=n,this.length-=n),wi(t.doc.store,this)}write(t,n){t.writeInfo(Bl),t.writeLen(this.length-n)}getMissing(t,n){return null}},Bt=class e{constructor(t){this.content=t}getLength(){return 1}getContent(){return[this.content]}isCountable(){return!0}copy(){return new e(this.content)}splice(t){throw H()}mergeWith(t){return!1}integrate(t,n){}delete(t){}gc(t){}write(t,n){t.writeBuf(this.content)}getRef(){return 3}},Ml=e=>new Bt(e.readBuf()),he=class e{constructor(t){this.len=t}getLength(){return this.len}getContent(){return[]}isCountable(){return!1}copy(){return new e(this.len)}splice(t){let n=new e(this.len-t);return this.len=t,n}mergeWith(t){return this.len+=t.len,!0}integrate(t,n){Le(t.deleteSet,n.id.client,n.id.clock,this.len),n.markDeleted()}delete(t){}gc(t){}write(t,n){t.writeLen(this.len-n)}getRef(){return 1}},Rl=e=>new he(e.readLen()),Xi=(e,t)=>new Tt({guid:e,...t,shouldLoad:t.shouldLoad||t.autoLoad||!1}),Mt=class e{constructor(t){t._item&&console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."),this.doc=t;let n={};this.opts=n,t.gc||(n.gc=!1),t.autoLoad&&(n.autoLoad=!0),t.meta!==null&&(n.meta=t.meta)}getLength(){return 1}getContent(){return[this.doc]}isCountable(){return!0}copy(){return new e(Xi(this.doc.guid,this.opts))}splice(t){throw H()}mergeWith(t){return!1}integrate(t,n){this.doc._item=n,t.subdocsAdded.add(this.doc),this.doc.shouldLoad&&t.subdocsLoaded.add(this.doc)}delete(t){t.subdocsAdded.has(this.doc)?t.subdocsAdded.delete(this.doc):t.subdocsRemoved.add(this.doc)}gc(t){}write(t,n){t.writeString(this.doc.guid),t.writeAny(this.opts)}getRef(){return 9}},$l=e=>new Mt(Xi(e.readString(),e.readAny())),at=class e{constructor(t){this.embed=t}getLength(){return 1}getContent(){return[this.embed]}isCountable(){return!0}copy(){return new e(this.embed)}splice(t){throw H()}mergeWith(t){return!1}integrate(t,n){}delete(t){}gc(t){}write(t,n){t.writeJSON(this.embed)}getRef(){return 5}},Fl=e=>new at(e.readJSON()),E=class e{constructor(t,n){this.key=t,this.value=n}getLength(){return 1}getContent(){return[]}isCountable(){return!1}copy(){return new e(this.key,this.value)}splice(t){throw H()}mergeWith(t){return!1}integrate(t,n){let r=n.parent;r._searchMarker=null,r._hasFormatting=!0}delete(t){}gc(t){}write(t,n){t.writeKey(this.key),t.writeJSON(this.value)}getRef(){return 6}},jl=e=>new E(e.readKey(),e.readJSON()),ze=class e{constructor(t){this.arr=t}getLength(){return this.arr.length}getContent(){return this.arr}isCountable(){return!0}copy(){return new e(this.arr)}splice(t){let n=new e(this.arr.slice(t));return this.arr=this.arr.slice(0,t),n}mergeWith(t){return this.arr=this.arr.concat(t.arr),!0}integrate(t,n){}delete(t){}gc(t){}write(t,n){let r=this.arr.length;t.writeLen(r-n);for(let s=n;s<r;s++){let i=this.arr[s];t.writeString(i===void 0?"undefined":JSON.stringify(i))}}getRef(){return 2}},ql=e=>{let t=e.readLen(),n=[];for(let r=0;r<t;r++){let s=e.readString();s==="undefined"?n.push(void 0):n.push(JSON.parse(s))}return new ze(n)},yt=class e{constructor(t){this.arr=t}getLength(){return this.arr.length}getContent(){return this.arr}isCountable(){return!0}copy(){return new e(this.arr)}splice(t){let n=new e(this.arr.slice(t));return this.arr=this.arr.slice(0,t),n}mergeWith(t){return this.arr=this.arr.concat(t.arr),!0}integrate(t,n){}delete(t){}gc(t){}write(t,n){let r=this.arr.length;t.writeLen(r-n);for(let s=n;s<r;s++){let i=this.arr[s];t.writeAny(i)}}getRef(){return 8}},Gl=e=>{let t=e.readLen(),n=[];for(let r=0;r<t;r++)n.push(e.readAny());return new yt(n)},Y=class e{constructor(t){this.str=t}getLength(){return this.str.length}getContent(){return this.str.split("")}isCountable(){return!0}copy(){return new e(this.str)}splice(t){let n=new e(this.str.slice(t));this.str=this.str.slice(0,t);let r=this.str.charCodeAt(t-1);return r>=55296&&r<=56319&&(this.str=this.str.slice(0,t-1)+"\uFFFD",n.str="\uFFFD"+n.str.slice(1)),n}mergeWith(t){return this.str+=t.str,!0}integrate(t,n){}delete(t){}gc(t){}write(t,n){t.writeString(n===0?this.str:this.str.slice(n))}getRef(){return 4}},zl=e=>new Y(e.readString()),Hl=[Al,Il,vl,Ol,Vl,Nl,Ll],Jl=0,Xl=1,Pl=2,Kl=3,Yl=4,Wl=5,Zl=6,K=class e{constructor(t){this.type=t}getLength(){return 1}getContent(){return[this.type]}isCountable(){return!0}copy(){return new e(this.type._copy())}splice(t){throw H()}mergeWith(t){return!1}integrate(t,n){this.type._integrate(t.doc,n)}delete(t){let n=this.type._start;for(;n!==null;)n.deleted?n.id.clock<(t.beforeState.get(n.id.client)||0)&&t._mergeStructs.push(n):n.delete(t),n=n.right;this.type._map.forEach(r=>{r.deleted?r.id.clock<(t.beforeState.get(r.id.client)||0)&&t._mergeStructs.push(r):r.delete(t)}),t.changed.delete(this.type)}gc(t){let n=this.type._start;for(;n!==null;)n.gc(t,!0),n=n.right;this.type._start=null,this.type._map.forEach(r=>{for(;r!==null;)r.gc(t,!0),r=r.left}),this.type._map=new Map}write(t,n){this.type._write(t)}getRef(){return 7}},Ql=e=>new K(Hl[e.readTypeRef()](e)),Mr=(e,t)=>{let n=t,r=0,s;do r>0&&(n=w(n.client,n.clock+r)),s=Ve(e,n),r=n.clock-s.id.clock,n=s.redone;while(n!==null&&s instanceof S);return{item:s,diff:r}},Zr=(e,t)=>{for(;e!==null&&e.keep!==t;)e.keep=t,e=e.parent._item},$n=(e,t,n)=>{let{client:r,clock:s}=t.id,i=new S(w(r,s+n),t,w(r,s+n-1),t.right,t.rightOrigin,t.parent,t.parentSub,t.content.splice(n));return t.deleted&&i.markDeleted(),t.keep&&(i.keep=!0),t.redone!==null&&(i.redone=w(t.redone.client,t.redone.clock+n)),t.right=i,i.right!==null&&(i.right.left=i),e._mergeStructs.push(i),i.parentSub!==null&&i.right===null&&i.parent._map.set(i.parentSub,i),t.length=n,i},ai=(e,t)=>fe(e,n=>Rt(n.deletions,t)),Pi=(e,t,n,r,s,i)=>{let o=e.doc,c=o.store,l=o.clientID,u=t.redone;if(u!==null)return M(e,u);let a=t.parent._item,h=null,d;if(a!==null&&a.deleted===!0){if(a.redone===null&&(!n.has(a)||Pi(e,a,n,r,s,i)===null))return null;for(;a.redone!==null;)a=M(e,a.redone)}let f=a===null?t.parent:a.content.type;if(t.parentSub===null){for(h=t.left,d=t;h!==null;){let x=h;for(;x!==null&&x.parent._item!==a;)x=x.redone===null?null:M(e,x.redone);if(x!==null&&x.parent._item===a){h=x;break}h=h.left}for(;d!==null;){let x=d;for(;x!==null&&x.parent._item!==a;)x=x.redone===null?null:M(e,x.redone);if(x!==null&&x.parent._item===a){d=x;break}d=d.right}}else if(d=null,t.right&&!s){for(h=t;h!==null&&h.right!==null&&(h.right.redone||Rt(r,h.right.id)||ai(i.undoStack,h.right.id)||ai(i.redoStack,h.right.id));)for(h=h.right;h.redone;)h=M(e,h.redone);if(h&&h.right!==null)return null}else h=f._map.get(t.parentSub)||null;let p=_(c,l),b=w(l,p),m=new S(b,h,h&&h.lastId,d,d&&d.id,f,t.parentSub,t.content.copy());return t.redone=b,Zr(m,!0),m.integrate(e,0),m},S=class e extends ae{constructor(t,n,r,s,i,o,c,l){super(t,l.getLength()),this.origin=r,this.left=n,this.right=s,this.rightOrigin=i,this.parent=o,this.parentSub=c,this.redone=null,this.content=l,this.info=this.content.isCountable()?2:0}set marker(t){(this.info&8)>0!==t&&(this.info^=8)}get marker(){return(this.info&8)>0}get keep(){return(this.info&1)>0}set keep(t){this.keep!==t&&(this.info^=1)}get countable(){return(this.info&2)>0}get deleted(){return(this.info&4)>0}set deleted(t){this.deleted!==t&&(this.info^=4)}markDeleted(){this.info|=4}getMissing(t,n){if(this.origin&&this.origin.client!==this.id.client&&this.origin.clock>=_(n,this.origin.client))return this.origin.client;if(this.rightOrigin&&this.rightOrigin.client!==this.id.client&&this.rightOrigin.clock>=_(n,this.rightOrigin.client))return this.rightOrigin.client;if(this.parent&&this.parent.constructor===ct&&this.id.client!==this.parent.client&&this.parent.clock>=_(n,this.parent.client))return this.parent.client;if(this.origin&&(this.left=ti(t,n,this.origin),this.origin=this.left.lastId),this.rightOrigin&&(this.right=M(t,this.rightOrigin),this.rightOrigin=this.right.id),this.left&&this.left.constructor===N||this.right&&this.right.constructor===N)this.parent=null;else if(!this.parent)this.left&&this.left.constructor===e&&(this.parent=this.left.parent,this.parentSub=this.left.parentSub),this.right&&this.right.constructor===e&&(this.parent=this.right.parent,this.parentSub=this.right.parentSub);else if(this.parent.constructor===ct){let r=Ve(n,this.parent);r.constructor===N?this.parent=null:this.parent=r.content.type}return null}integrate(t,n){if(n>0&&(this.id.clock+=n,this.left=ti(t,t.doc.store,w(this.id.client,this.id.clock-1)),this.origin=this.left.lastId,this.content=this.content.splice(n),this.length-=n),this.parent){if(!this.left&&(!this.right||this.right.left!==null)||this.left&&this.left.right!==this.right){let r=this.left,s;if(r!==null)s=r.right;else if(this.parentSub!==null)for(s=this.parent._map.get(this.parentSub)||null;s!==null&&s.left!==null;)s=s.left;else s=this.parent._start;let i=new Set,o=new Set;for(;s!==null&&s!==this.right;){if(o.add(s),i.add(s),At(this.origin,s.origin)){if(s.id.client<this.id.client)r=s,i.clear();else if(At(this.rightOrigin,s.rightOrigin))break}else if(s.origin!==null&&o.has(Ve(t.doc.store,s.origin)))i.has(Ve(t.doc.store,s.origin))||(r=s,i.clear());else break;s=s.right}this.left=r}if(this.left!==null){let r=this.left.right;this.right=r,this.left.right=this}else{let r;if(this.parentSub!==null)for(r=this.parent._map.get(this.parentSub)||null;r!==null&&r.left!==null;)r=r.left;else r=this.parent._start,this.parent._start=this;this.right=r}this.right!==null?this.right.left=this:this.parentSub!==null&&(this.parent._map.set(this.parentSub,this),this.left!==null&&this.left.delete(t)),this.parentSub===null&&this.countable&&!this.deleted&&(this.parent._length+=this.length),wi(t.doc.store,this),this.content.integrate(t,this),ni(t,this.parent,this.parentSub),(this.parent._item!==null&&this.parent._item.deleted||this.parentSub!==null&&this.right!==null)&&this.delete(t)}else new N(this.id,this.length).integrate(t,0)}get next(){let t=this.right;for(;t!==null&&t.deleted;)t=t.right;return t}get prev(){let t=this.left;for(;t!==null&&t.deleted;)t=t.left;return t}get lastId(){return this.length===1?this.id:w(this.id.client,this.id.clock+this.length-1)}mergeWith(t){if(this.constructor===t.constructor&&At(t.origin,this.lastId)&&this.right===t&&At(this.rightOrigin,t.rightOrigin)&&this.id.client===t.id.client&&this.id.clock+this.length===t.id.clock&&this.deleted===t.deleted&&this.redone===null&&t.redone===null&&this.content.constructor===t.content.constructor&&this.content.mergeWith(t.content)){let n=this.parent._searchMarker;return n&&n.forEach(r=>{r.p===t&&(r.p=this,!this.deleted&&this.countable&&(r.index-=this.length))}),t.keep&&(this.keep=!0),this.right=t.right,this.right!==null&&(this.right.left=this),this.length+=t.length,!0}return!1}delete(t){if(!this.deleted){let n=this.parent;this.countable&&this.parentSub===null&&(n._length-=this.length),this.markDeleted(),Le(t.deleteSet,this.id.client,this.id.clock,this.length),ni(t,n,this.parentSub),this.content.delete(t)}}gc(t,n){if(!this.deleted)throw D();this.content.gc(t),n?cl(t,this,new N(this.id,this.length)):this.content=new he(this.length)}write(t,n){let r=n>0?w(this.id.client,this.id.clock+n-1):this.origin,s=this.rightOrigin,i=this.parentSub,o=this.content.getRef()&31|(r===null?0:128)|(s===null?0:64)|(i===null?0:32);if(t.writeInfo(o),r!==null&&t.writeLeftID(r),s!==null&&t.writeRightID(s),r===null&&s===null){let c=this.parent;if(c._item!==void 0){let l=c._item;if(l===null){let u=Hr(c);t.writeParentInfo(!0),t.writeString(u)}else t.writeParentInfo(!1),t.writeLeftID(l.id)}else c.constructor===String?(t.writeParentInfo(!0),t.writeString(c)):c.constructor===ct?(t.writeParentInfo(!1),t.writeLeftID(c)):D();i!==null&&t.writeString(i)}this.content.write(t,n)}},Ki=(e,t)=>ta[t&31](e),ta=[()=>{D()},Rl,ql,Ml,zl,Fl,jl,Ql,Gl,$l,()=>{D()}],ea=10,O=class extends ae{get deleted(){return!0}delete(){}mergeWith(t){return this.constructor!==t.constructor?!1:(this.length+=t.length,!0)}integrate(t,n){D()}write(t,n){t.writeInfo(ea),g(t.restEncoder,this.length-n)}getMissing(t,n){return null}},Yi=typeof globalThis!="undefined"?globalThis:typeof window!="undefined"?window:typeof global!="undefined"?global:{},Wi="__ $YJS$ __";Yi[Wi]===!0&&console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438");Yi[Wi]=!0;return so(na);})();
|
|
11307
|
+
return Y;
|
|
11308
|
+
}
|
|
11309
|
+
|
|
10827
11310
|
// ───────────────────────── Entry point
|
|
10828
11311
|
// Nothing is added to the page here: the UI, the fullscreen hook and tilt-to-landscape
|
|
10829
11312
|
// start only once real media is found (see UI_GATE / VIDEO_DETECTOR._setTarget).
|