touch-coop 2.2.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -15
- package/demos/gamepad/index.html +4 -1
- package/demos/match.html +59 -111
- package/dist/index.cjs +2 -2
- package/dist/index.global.js +2 -2
- package/dist/index.mjs +49 -36
- package/dist/match.d.ts +3 -1
- package/dist/match.d.ts.map +1 -1
- package/dist/player.d.ts +2 -1
- package/dist/player.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/match.ts +13 -2
- package/src/player.ts +11 -3
- package/dist/encoding.d.ts +0 -3
- package/dist/encoding.d.ts.map +0 -1
- package/media/demo.png +0 -0
- package/src/encoding.ts +0 -42
package/README.md
CHANGED
|
@@ -43,12 +43,13 @@ npm install touch-coop
|
|
|
43
43
|
|
|
44
44
|
The library expects your game to use the `Match` and `Player` classes. Your game will require a minimum of two pages with unique URLs:
|
|
45
45
|
|
|
46
|
-
### 1. Match
|
|
46
|
+
### 1. Match (Shared TV/Monitor)
|
|
47
47
|
|
|
48
|
-
The main game page hosts the game and creates a `Match` instance. This page uses `
|
|
48
|
+
The main game page hosts the game and creates a `Match` instance. This page uses `createLobby()` to generate a QR code that players can scan to join the game.
|
|
49
49
|
|
|
50
50
|
```ts
|
|
51
51
|
import { Match, PlayerEvent } from "touch-coop";
|
|
52
|
+
import { useCallback, useState } from "react";
|
|
52
53
|
|
|
53
54
|
const gamePadURL = "http://localhost:8080/demos/gamepad";
|
|
54
55
|
|
|
@@ -56,30 +57,51 @@ function handlePlayerEvent(event: PlayerEvent) {
|
|
|
56
57
|
switch (event.action) {
|
|
57
58
|
case "JOIN":
|
|
58
59
|
console.log(
|
|
59
|
-
`Player ${event.playerId} joined the game.`
|
|
60
|
+
`Player ${event.playerId} ${event.playerName} joined the game.`
|
|
60
61
|
);
|
|
61
62
|
break;
|
|
62
63
|
case "LEAVE":
|
|
63
64
|
console.log(
|
|
64
|
-
`Player ${event.playerId} left the game.`
|
|
65
|
+
`Player ${event.playerId} ${event.playerName} left the game.`
|
|
65
66
|
);
|
|
66
67
|
break;
|
|
67
68
|
case "MOVE":
|
|
68
69
|
console.log(
|
|
69
|
-
`Player ${event.playerId} pressed ${event.button}`
|
|
70
|
+
`Player ${event.playerId} ${event.playerName} pressed ${event.button}`
|
|
70
71
|
);
|
|
71
72
|
break;
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
export function Lobby() {
|
|
77
|
+
const [dataUrl, setDataUrl] = React.useState<string | null>(null);
|
|
78
|
+
const createLobby = useCallback(() => {
|
|
79
|
+
(async () => {
|
|
80
|
+
const match = new Match(
|
|
81
|
+
gamePadURL,
|
|
82
|
+
handlePlayerEvent
|
|
83
|
+
);
|
|
84
|
+
const { dataUrl } = await match.createLobby();
|
|
85
|
+
setDataUrl(dataUrl);
|
|
86
|
+
})();
|
|
87
|
+
}, []);
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
return dataUrl === null ? (
|
|
90
|
+
<div>
|
|
91
|
+
<button onClick={createLobby}>
|
|
92
|
+
Create Lobby
|
|
93
|
+
</button>
|
|
94
|
+
</div>
|
|
95
|
+
) :(
|
|
96
|
+
<div>
|
|
97
|
+
<p>Scan the QR code below to join the game:</p>
|
|
98
|
+
<img src={dataUrl} alt="GamePad QR Code" />
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
80
102
|
```
|
|
81
103
|
|
|
82
|
-
### 2.
|
|
104
|
+
### 2. Virtual Controller (Mobile device)
|
|
83
105
|
|
|
84
106
|
Each player scans a QR code to join the game. The QR code contains a unique URL that opens a web page with touch controls. This page uses the `Player` class to connect to the game match with `player.joinMatch()` and send input events with `player.sendMove("X")`.
|
|
85
107
|
|
|
@@ -94,9 +116,10 @@ export default function GamePad() {
|
|
|
94
116
|
|
|
95
117
|
React.useEffect(() => {
|
|
96
118
|
(async () => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
119
|
+
const playerName = prompt("Enter your player name:");
|
|
120
|
+
await player.joinMatch(playerName);
|
|
121
|
+
setLoading(false);
|
|
122
|
+
})();
|
|
100
123
|
}, []);
|
|
101
124
|
|
|
102
125
|
if (loading) {
|
|
@@ -138,8 +161,6 @@ export default function GamePad() {
|
|
|
138
161
|
|
|
139
162
|
You can try a live demo of TouchCoop at [https://SlaneyEE.github.io/touch-coop/demos/match.html](https://SlaneyEE.github.io/touch-coop/demos/match.html).
|
|
140
163
|
|
|
141
|
-

|
|
142
|
-
|
|
143
164
|
The demo contains a simple game where players can join by scaning a QR Code and use their mobile devices as controllers. Each player can use the on-screen buttons to send input events to the game.
|
|
144
165
|
|
|
145
166
|
The game page is [./demos/match.html](./demos/match.html). The QR code redirects players to [./demos/gamepad/index.html](./demos/gamepad/index.html).
|
package/demos/gamepad/index.html
CHANGED
|
@@ -43,7 +43,10 @@
|
|
|
43
43
|
document.getElementById("joinBtn").onclick = async () => {
|
|
44
44
|
document.getElementById("joinBtn").style.display = "none";
|
|
45
45
|
document.getElementById("gamepad").style.display = "block";
|
|
46
|
-
|
|
46
|
+
let playerName = prompt("Enter your player name:");
|
|
47
|
+
if (!playerName || !playerName.trim()) playerName = "Player";
|
|
48
|
+
playerName = playerName.trim();
|
|
49
|
+
await player.joinMatch(playerName);
|
|
47
50
|
function sendButtonEvent(btn) {
|
|
48
51
|
player.sendMove(btn);
|
|
49
52
|
}
|
package/demos/match.html
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<!DOCTYPE html>
|
|
3
2
|
<html lang="en">
|
|
4
3
|
<head>
|
|
5
4
|
<meta charset="UTF-8" />
|
|
@@ -7,145 +6,94 @@
|
|
|
7
6
|
<title>Touch Coop Demo</title>
|
|
8
7
|
<style>
|
|
9
8
|
body { background-color: black; color: white; }
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
textarea { width: 100%; resize: vertical; height: 50vh; }
|
|
9
|
+
img.qr { width: 100%; max-width: 300px; }
|
|
10
|
+
textarea { width: 100%; resize: vertical; height: 30vh; }
|
|
11
|
+
#players-container { display: flex; flex-wrap: wrap; justify-content: center; }
|
|
12
|
+
.player-column { flex: 1; min-width: 250px; margin: 10px; padding: 10px; border: 1px solid #ccc; background-color: #222; }
|
|
15
13
|
</style>
|
|
16
14
|
</head>
|
|
17
15
|
<body>
|
|
18
16
|
<image src="https://github.com/SlaneyEE/touch-coop/raw/main/media/logo.png" alt="Touch Coop Logo" style="width:200px; display:block; margin:auto; margin-top: 2rem;" />
|
|
19
17
|
<h1>TouchCoop Demo</h1>
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<th>Player 4</th>
|
|
26
|
-
</tr>
|
|
27
|
-
<tr>
|
|
28
|
-
<td id="cell-0">
|
|
29
|
-
<div id="player-id-0" style="min-height:1.5em;"></div>
|
|
30
|
-
<div id="qr-0"><button onclick="joinPlayer(0)">Join</button></div>
|
|
31
|
-
<div id="area-0" style="display:none; margin-top:12px;">
|
|
32
|
-
<label for="messages-0">Player 1 Messages:</label><br />
|
|
33
|
-
<textarea id="messages-0" rows="6" cols="30" readonly style="resize:vertical;"></textarea>
|
|
34
|
-
</div>
|
|
35
|
-
</td>
|
|
36
|
-
<td id="cell-1">
|
|
37
|
-
<div id="player-id-1" style="min-height:1.5em;"></div>
|
|
38
|
-
<div id="qr-1"><button onclick="joinPlayer(1)">Join</button></div>
|
|
39
|
-
<div id="area-1" style="display:none; margin-top:12px;">
|
|
40
|
-
<label for="messages-1">Player 2 Messages:</label><br />
|
|
41
|
-
<textarea id="messages-1" rows="6" cols="30" readonly style="resize:vertical;"></textarea>
|
|
42
|
-
</div>
|
|
43
|
-
</td>
|
|
44
|
-
<td id="cell-2">
|
|
45
|
-
<div id="player-id-2" style="min-height:1.5em;"></div>
|
|
46
|
-
<div id="qr-2"><button onclick="joinPlayer(2)">Join</button></div>
|
|
47
|
-
<div id="area-2" style="display:none; margin-top:12px;">
|
|
48
|
-
<label for="messages-2">Player 3 Messages:</label><br />
|
|
49
|
-
<textarea id="messages-2" rows="6" cols="30" readonly style="resize:vertical;"></textarea>
|
|
50
|
-
</div>
|
|
51
|
-
</td>
|
|
52
|
-
<td id="cell-3">
|
|
53
|
-
<div id="player-id-3" style="min-height:1.5em;"></div>
|
|
54
|
-
<div id="qr-3"><button onclick="joinPlayer(3)">Join</button></div>
|
|
55
|
-
<div id="area-3" style="display:none; margin-top:12px;">
|
|
56
|
-
<label for="messages-3">Player 4 Messages:</label><br />
|
|
57
|
-
<textarea id="messages-3" rows="6" cols="30" readonly style="resize:vertical;"></textarea>
|
|
58
|
-
</div>
|
|
59
|
-
</td>
|
|
60
|
-
</tr>
|
|
61
|
-
</table>
|
|
18
|
+
<div id="lobby-area" style="text-align: center; margin-bottom: 2rem;">
|
|
19
|
+
<button onclick="createLobby()" style="padding: 10px 20px; font-size: 18px;">Create Lobby</button>
|
|
20
|
+
<div id="lobby-qr" style="display: none; margin-top: 1rem;"></div>
|
|
21
|
+
</div>
|
|
22
|
+
<div id="players-container"></div>
|
|
62
23
|
<script src="../dist/index.global.js"></script>
|
|
63
24
|
<script>
|
|
25
|
+
const players = {}; // playerId -> { div, textarea }
|
|
64
26
|
|
|
65
|
-
function
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
27
|
+
function createLobby() {
|
|
28
|
+
const lobbyDiv = document.getElementById('lobby-qr');
|
|
29
|
+
lobbyDiv.style.display = 'block';
|
|
30
|
+
lobbyDiv.innerHTML = 'Loading...';
|
|
31
|
+
match.createLobby().then(({ dataUrl, shareURL }) => {
|
|
32
|
+
lobbyDiv.innerHTML = `
|
|
33
|
+
<img class='qr' src='${dataUrl}' alt='QR Code' /><br>
|
|
34
|
+
<a href='${shareURL}' target='_blank' style='color: white;'>Connect</a>
|
|
35
|
+
`;
|
|
36
|
+
}).catch(err => {
|
|
37
|
+
lobbyDiv.innerHTML = `<span style='color:red;'>Error: ${err.message}</span>`;
|
|
38
|
+
});
|
|
72
39
|
}
|
|
73
40
|
|
|
74
41
|
function handlePlayerEvent(event) {
|
|
75
|
-
|
|
76
|
-
for (let i = 0; i < 4; i++) {
|
|
77
|
-
const div = document.getElementById(`qr-${i}`);
|
|
78
|
-
if (div.dataset.playerId === event.playerId) {
|
|
79
|
-
idx = i;
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (idx === -1 && event.action === "JOIN") {
|
|
84
|
-
for (let i = 0; i < 4; i++) {
|
|
85
|
-
const div = document.getElementById(`qr-${i}`);
|
|
86
|
-
if (!div.dataset.playerId) {
|
|
87
|
-
div.dataset.playerId = event.playerId;
|
|
88
|
-
idx = i;
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (idx === -1) return;
|
|
94
|
-
const qrDiv = document.getElementById(`qr-${idx}`);
|
|
95
|
-
const areaDiv = document.getElementById(`area-${idx}`);
|
|
96
|
-
const area = document.getElementById(`messages-${idx}`);
|
|
42
|
+
const playerId = event.playerId;
|
|
97
43
|
switch (event.action) {
|
|
98
44
|
case "JOIN": {
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
45
|
+
// Add join message to all players
|
|
46
|
+
for (const p of Object.values(players)) {
|
|
47
|
+
p.textarea.value += `${event.playerName} joined!\n`;
|
|
48
|
+
}
|
|
49
|
+
if (!players[playerId]) {
|
|
50
|
+
const playerDiv = document.createElement('div');
|
|
51
|
+
playerDiv.className = 'player-column';
|
|
52
|
+
playerDiv.innerHTML = `
|
|
53
|
+
<div style="margin-bottom: 10px;">Player ID: ${playerId} ${event.playerName}</div>
|
|
54
|
+
<label>Messages:</label><br>
|
|
55
|
+
<textarea rows="10" readonly></textarea>
|
|
56
|
+
`;
|
|
57
|
+
document.getElementById('players-container').appendChild(playerDiv);
|
|
58
|
+
players[playerId] = {
|
|
59
|
+
div: playerDiv,
|
|
60
|
+
textarea: playerDiv.querySelector('textarea')
|
|
61
|
+
};
|
|
62
|
+
}
|
|
107
63
|
break;
|
|
108
64
|
}
|
|
109
65
|
case "LEAVE": {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
66
|
+
// Add leave message to all players
|
|
67
|
+
for (const p of Object.values(players)) {
|
|
68
|
+
p.textarea.value += `${event.playerName} Left!\n`;
|
|
69
|
+
}
|
|
70
|
+
if (players[playerId]) {
|
|
71
|
+
players[playerId].div.remove();
|
|
72
|
+
delete players[playerId];
|
|
73
|
+
}
|
|
117
74
|
break;
|
|
118
75
|
}
|
|
119
76
|
case "MOVE":
|
|
120
|
-
|
|
77
|
+
if (players[playerId]) {
|
|
78
|
+
players[playerId].textarea.value += `${event.playerName} Pressed ${event.button}\n`;
|
|
79
|
+
}
|
|
121
80
|
break;
|
|
122
81
|
default:
|
|
123
|
-
|
|
82
|
+
if (players[playerId]) {
|
|
83
|
+
players[playerId].textarea.value += JSON.stringify(event) + '\n';
|
|
84
|
+
}
|
|
124
85
|
break;
|
|
125
86
|
}
|
|
126
|
-
|
|
87
|
+
// Scroll all textareas
|
|
88
|
+
for (const p of Object.values(players)) {
|
|
89
|
+
p.textarea.scrollTop = p.textarea.scrollHeight;
|
|
90
|
+
}
|
|
127
91
|
}
|
|
128
92
|
|
|
129
93
|
const match = new TouchCoop.Match(
|
|
130
94
|
"http://localhost:8080/demos/gamepad",
|
|
131
95
|
handlePlayerEvent
|
|
132
96
|
);
|
|
133
|
-
|
|
134
|
-
window.joinPlayer = async function(idx) {
|
|
135
|
-
const qrDiv = document.getElementById(`qr-${idx}`);
|
|
136
|
-
const playerIdDiv = document.getElementById(`player-id-${idx}`);
|
|
137
|
-
qrDiv.innerHTML = 'Loading...';
|
|
138
|
-
playerIdDiv.textContent = '';
|
|
139
|
-
try {
|
|
140
|
-
const { dataUrl, shareURL } = await match.requestNewPlayerToJoin();
|
|
141
|
-
qrDiv.innerHTML = `
|
|
142
|
-
<img class='qr' src='${dataUrl}' alt='QR Code' /></br>
|
|
143
|
-
<a href='${shareURL}' target='_blank'>Connect</a>
|
|
144
|
-
`;
|
|
145
|
-
} catch (err) {
|
|
146
|
-
qrDiv.innerHTML = `<span style='color:red;'>Error</span>`;
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
97
|
</script>
|
|
150
98
|
</body>
|
|
151
99
|
</html>
|
package/dist/index.cjs
CHANGED
|
@@ -38,11 +38,11 @@ a=extmap-allow-mixed`)!==-1){const s=i.sdp.split(`
|
|
|
38
38
|
isIOS:${this.isIOS}
|
|
39
39
|
isWebRTCSupported:${this.isWebRTCSupported()}
|
|
40
40
|
isBrowserSupported:${this.isBrowserSupported()}
|
|
41
|
-
isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`}constructor(){this.isIOS=typeof navigator<"u"?["iPad","iPhone","iPod"].includes(navigator.platform):!1,this.supportedBrowsers=["firefox","chrome","safari"],this.minFirefoxVersion=59,this.minChromeVersion=72,this.minSafariVersion=605}},er=r=>!r||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(r),En=()=>Math.random().toString(36).slice(2),gt={iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:["turn:eu-0.turn.peerjs.com:3478","turn:us-0.turn.peerjs.com:3478"],username:"peerjs",credential:"peerjsp"}],sdpSemantics:"unified-plan"};class tr extends kn{noop(){}blobToArrayBuffer(e,n){const t=new FileReader;return t.onload=function(i){i.target&&n(i.target.result)},t.readAsArrayBuffer(e),t}binaryStringToArrayBuffer(e){const n=new Uint8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t)&255;return n.buffer}isSecure(){return location.protocol==="https:"}constructor(...e){super(...e),this.CLOUD_HOST="0.peerjs.com",this.CLOUD_PORT=443,this.chunkedBrowsers={Chrome:1,chrome:1},this.defaultConfig=gt,this.browser=Z.getBrowser(),this.browserVersion=Z.getVersion(),this.pack=Jt,this.unpack=qt,this.supports=(function(){const n={browser:Z.isBrowserSupported(),webRTC:Z.isWebRTCSupported(),audioVideo:!1,data:!1,binaryBlob:!1,reliable:!1};if(!n.webRTC)return n;let t;try{t=new RTCPeerConnection(gt),n.audioVideo=!0;let i;try{i=t.createDataChannel("_PEERJSTEST",{ordered:!0}),n.data=!0,n.reliable=!!i.ordered;try{i.binaryType="blob",n.binaryBlob=!Z.isIOS}catch{}}catch{}finally{i&&i.close()}}catch{}finally{t&&t.close()}return n})(),this.validateId=er,this.randomToken=En}}const N=new tr,nr="PeerJS: ";class rr{get logLevel(){return this._logLevel}set logLevel(e){this._logLevel=e}log(...e){this._logLevel>=3&&this._print(3,...e)}warn(...e){this._logLevel>=2&&this._print(2,...e)}error(...e){this._logLevel>=1&&this._print(1,...e)}setLogFunction(e){this._print=e}_print(e,...n){const t=[nr,...n];for(const i in t)t[i]instanceof Error&&(t[i]="("+t[i].name+") "+t[i].message);e>=3?console.log(...t):e>=2?console.warn("WARNING",...t):e>=1&&console.error("ERROR",...t)}constructor(){this._logLevel=0}}var p=new rr,Ze={},ir=Object.prototype.hasOwnProperty,O="~";function ne(){}Object.create&&(ne.prototype=Object.create(null),new ne().__proto__||(O=!1));function sr(r,e,n){this.fn=r,this.context=e,this.once=n||!1}function xn(r,e,n,t,i){if(typeof n!="function")throw new TypeError("The listener must be a function");var s=new sr(n,t||r,i),o=O?O+e:e;return r._events[o]?r._events[o].fn?r._events[o]=[r._events[o],s]:r._events[o].push(s):(r._events[o]=s,r._eventsCount++),r}function ue(r,e){--r._eventsCount===0?r._events=new ne:delete r._events[e]}function B(){this._events=new ne,this._eventsCount=0}B.prototype.eventNames=function(){var e=[],n,t;if(this._eventsCount===0)return e;for(t in n=this._events)ir.call(n,t)&&e.push(O?t.slice(1):t);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(n)):e};B.prototype.listeners=function(e){var n=O?O+e:e,t=this._events[n];if(!t)return[];if(t.fn)return[t.fn];for(var i=0,s=t.length,o=new Array(s);i<s;i++)o[i]=t[i].fn;return o};B.prototype.listenerCount=function(e){var n=O?O+e:e,t=this._events[n];return t?t.fn?1:t.length:0};B.prototype.emit=function(e,n,t,i,s,o){var a=O?O+e:e;if(!this._events[a])return!1;var c=this._events[a],f=arguments.length,u,l;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),f){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,n),!0;case 3:return c.fn.call(c.context,n,t),!0;case 4:return c.fn.call(c.context,n,t,i),!0;case 5:return c.fn.call(c.context,n,t,i,s),!0;case 6:return c.fn.call(c.context,n,t,i,s,o),!0}for(l=1,u=new Array(f-1);l<f;l++)u[l-1]=arguments[l];c.fn.apply(c.context,u)}else{var d=c.length,h;for(l=0;l<d;l++)switch(c[l].once&&this.removeListener(e,c[l].fn,void 0,!0),f){case 1:c[l].fn.call(c[l].context);break;case 2:c[l].fn.call(c[l].context,n);break;case 3:c[l].fn.call(c[l].context,n,t);break;case 4:c[l].fn.call(c[l].context,n,t,i);break;default:if(!u)for(h=1,u=new Array(f-1);h<f;h++)u[h-1]=arguments[h];c[l].fn.apply(c[l].context,u)}}return!0};B.prototype.on=function(e,n,t){return xn(this,e,n,t,!1)};B.prototype.once=function(e,n,t){return xn(this,e,n,t,!0)};B.prototype.removeListener=function(e,n,t,i){var s=O?O+e:e;if(!this._events[s])return this;if(!n)return ue(this,s),this;var o=this._events[s];if(o.fn)o.fn===n&&(!i||o.once)&&(!t||o.context===t)&&ue(this,s);else{for(var a=0,c=[],f=o.length;a<f;a++)(o[a].fn!==n||i&&!o[a].once||t&&o[a].context!==t)&&c.push(o[a]);c.length?this._events[s]=c.length===1?c[0]:c:ue(this,s)}return this};B.prototype.removeAllListeners=function(e){var n;return e?(n=O?O+e:e,this._events[n]&&ue(this,n)):(this._events=new ne,this._eventsCount=0),this};B.prototype.off=B.prototype.removeListener;B.prototype.addListener=B.prototype.on;B.prefixed=O;B.EventEmitter=B;Ze=B;var G={};J(G,"ConnectionType",()=>V);J(G,"PeerErrorType",()=>D);J(G,"BaseConnectionErrorType",()=>We);J(G,"DataConnectionErrorType",()=>et);J(G,"SerializationType",()=>pe);J(G,"SocketEventType",()=>w);J(G,"ServerMessageType",()=>L);var V=(function(r){return r.Data="data",r.Media="media",r})({}),D=(function(r){return r.BrowserIncompatible="browser-incompatible",r.Disconnected="disconnected",r.InvalidID="invalid-id",r.InvalidKey="invalid-key",r.Network="network",r.PeerUnavailable="peer-unavailable",r.SslUnavailable="ssl-unavailable",r.ServerError="server-error",r.SocketError="socket-error",r.SocketClosed="socket-closed",r.UnavailableID="unavailable-id",r.WebRTC="webrtc",r})({}),We=(function(r){return r.NegotiationFailed="negotiation-failed",r.ConnectionClosed="connection-closed",r})({}),et=(function(r){return r.NotOpenYet="not-open-yet",r.MessageToBig="message-too-big",r})({}),pe=(function(r){return r.Binary="binary",r.BinaryUTF8="binary-utf8",r.JSON="json",r.None="raw",r})({}),w=(function(r){return r.Message="message",r.Disconnected="disconnected",r.Error="error",r.Close="close",r})({}),L=(function(r){return r.Heartbeat="HEARTBEAT",r.Candidate="CANDIDATE",r.Offer="OFFER",r.Answer="ANSWER",r.Open="OPEN",r.Error="ERROR",r.IdTaken="ID-TAKEN",r.InvalidKey="INVALID-KEY",r.Leave="LEAVE",r.Expire="EXPIRE",r})({});const In="1.5.5";class or extends Ze.EventEmitter{constructor(e,n,t,i,s,o=5e3){super(),this.pingInterval=o,this._disconnected=!0,this._messagesQueue=[];const a=e?"wss://":"ws://";this._baseUrl=a+n+":"+t+i+"peerjs?key="+s}start(e,n){this._id=e;const t=`${this._baseUrl}&id=${e}&token=${n}`;this._socket||!this._disconnected||(this._socket=new WebSocket(t+"&version="+In),this._disconnected=!1,this._socket.onmessage=i=>{let s;try{s=JSON.parse(i.data),p.log("Server message received:",s)}catch{p.log("Invalid server message",i.data);return}this.emit(w.Message,s)},this._socket.onclose=i=>{this._disconnected||(p.log("Socket closed.",i),this._cleanup(),this._disconnected=!0,this.emit(w.Disconnected))},this._socket.onopen=()=>{this._disconnected||(this._sendQueuedMessages(),p.log("Socket open"),this._scheduleHeartbeat())})}_scheduleHeartbeat(){this._wsPingTimer=setTimeout(()=>{this._sendHeartbeat()},this.pingInterval)}_sendHeartbeat(){if(!this._wsOpen()){p.log("Cannot send heartbeat, because socket closed");return}const e=JSON.stringify({type:L.Heartbeat});this._socket.send(e),this._scheduleHeartbeat()}_wsOpen(){return!!this._socket&&this._socket.readyState===1}_sendQueuedMessages(){const e=[...this._messagesQueue];this._messagesQueue=[];for(const n of e)this.send(n)}send(e){if(this._disconnected)return;if(!this._id){this._messagesQueue.push(e);return}if(!e.type){this.emit(w.Error,"Invalid message");return}if(!this._wsOpen())return;const n=JSON.stringify(e);this._socket.send(n)}close(){this._disconnected||(this._cleanup(),this._disconnected=!0)}_cleanup(){this._socket&&(this._socket.onopen=this._socket.onmessage=this._socket.onclose=null,this._socket.close(),this._socket=void 0),clearTimeout(this._wsPingTimer)}}class Dn{constructor(e){this.connection=e}startConnection(e){const n=this._startPeerConnection();if(this.connection.peerConnection=n,this.connection.type===V.Media&&e._stream&&this._addTracksToConnection(e._stream,n),e.originator){const t=this.connection,i={ordered:!!e.reliable},s=n.createDataChannel(t.label,i);t._initializeDataChannel(s),this._makeOffer()}else this.handleSDP("OFFER",e.sdp)}_startPeerConnection(){p.log("Creating RTCPeerConnection.");const e=new RTCPeerConnection(this.connection.provider.options.config);return this._setupListeners(e),e}_setupListeners(e){const n=this.connection.peer,t=this.connection.connectionId,i=this.connection.type,s=this.connection.provider;p.log("Listening for ICE candidates."),e.onicecandidate=o=>{!o.candidate||!o.candidate.candidate||(p.log(`Received ICE candidates for ${n}:`,o.candidate),s.socket.send({type:L.Candidate,payload:{candidate:o.candidate,type:i,connectionId:t},dst:n}))},e.oniceconnectionstatechange=()=>{switch(e.iceConnectionState){case"failed":p.log("iceConnectionState is failed, closing connections to "+n),this.connection.emitError(We.NegotiationFailed,"Negotiation of connection to "+n+" failed."),this.connection.close();break;case"closed":p.log("iceConnectionState is closed, closing connections to "+n),this.connection.emitError(We.ConnectionClosed,"Connection to "+n+" closed."),this.connection.close();break;case"disconnected":p.log("iceConnectionState changed to disconnected on the connection with "+n);break;case"completed":e.onicecandidate=()=>{};break}this.connection.emit("iceStateChanged",e.iceConnectionState)},p.log("Listening for data channel"),e.ondatachannel=o=>{p.log("Received data channel");const a=o.channel;s.getConnection(n,t)._initializeDataChannel(a)},p.log("Listening for remote stream"),e.ontrack=o=>{p.log("Received remote stream");const a=o.streams[0],c=s.getConnection(n,t);if(c.type===V.Media){const f=c;this._addStreamToMediaConnection(a,f)}}}cleanup(){p.log("Cleaning up PeerConnection to "+this.connection.peer);const e=this.connection.peerConnection;if(!e)return;this.connection.peerConnection=null,e.onicecandidate=e.oniceconnectionstatechange=e.ondatachannel=e.ontrack=()=>{};const n=e.signalingState!=="closed";let t=!1;const i=this.connection.dataChannel;i&&(t=!!i.readyState&&i.readyState!=="closed"),(n||t)&&e.close()}async _makeOffer(){const e=this.connection.peerConnection,n=this.connection.provider;try{const t=await e.createOffer(this.connection.options.constraints);p.log("Created offer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(t.sdp=this.connection.options.sdpTransform(t.sdp)||t.sdp);try{await e.setLocalDescription(t),p.log("Set localDescription:",t,`for:${this.connection.peer}`);let i={sdp:t,type:this.connection.type,connectionId:this.connection.connectionId,metadata:this.connection.metadata};if(this.connection.type===V.Data){const s=this.connection;i={...i,label:s.label,reliable:s.reliable,serialization:s.serialization}}n.socket.send({type:L.Offer,payload:i,dst:this.connection.peer})}catch(i){i!="OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"&&(n.emitError(D.WebRTC,i),p.log("Failed to setLocalDescription, ",i))}}catch(t){n.emitError(D.WebRTC,t),p.log("Failed to createOffer, ",t)}}async _makeAnswer(){const e=this.connection.peerConnection,n=this.connection.provider;try{const t=await e.createAnswer();p.log("Created answer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(t.sdp=this.connection.options.sdpTransform(t.sdp)||t.sdp);try{await e.setLocalDescription(t),p.log("Set localDescription:",t,`for:${this.connection.peer}`),n.socket.send({type:L.Answer,payload:{sdp:t,type:this.connection.type,connectionId:this.connection.connectionId},dst:this.connection.peer})}catch(i){n.emitError(D.WebRTC,i),p.log("Failed to setLocalDescription, ",i)}}catch(t){n.emitError(D.WebRTC,t),p.log("Failed to create answer, ",t)}}async handleSDP(e,n){n=new RTCSessionDescription(n);const t=this.connection.peerConnection,i=this.connection.provider;p.log("Setting remote description",n);const s=this;try{await t.setRemoteDescription(n),p.log(`Set remoteDescription:${e} for:${this.connection.peer}`),e==="OFFER"&&await s._makeAnswer()}catch(o){i.emitError(D.WebRTC,o),p.log("Failed to setRemoteDescription, ",o)}}async handleCandidate(e){p.log("handleCandidate:",e);try{await this.connection.peerConnection.addIceCandidate(e),p.log(`Added ICE candidate for:${this.connection.peer}`)}catch(n){this.connection.provider.emitError(D.WebRTC,n),p.log("Failed to handleCandidate, ",n)}}_addTracksToConnection(e,n){if(p.log(`add tracks from stream ${e.id} to peer connection`),!n.addTrack)return p.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");e.getTracks().forEach(t=>{n.addTrack(t,e)})}_addStreamToMediaConnection(e,n){p.log(`add stream ${e.id} to media connection ${n.connectionId}`),n.addStream(e)}}class Mn extends Ze.EventEmitter{emitError(e,n){p.error("Error:",n),this.emit("error",new ar(`${e}`,n))}}class ar extends Error{constructor(e,n){typeof n=="string"?super(n):(super(),Object.assign(this,n)),this.type=e}}class An extends Mn{get open(){return this._open}constructor(e,n,t){super(),this.peer=e,this.provider=n,this.options=t,this._open=!1,this.metadata=t.metadata}}class le extends An{static#e=this.ID_PREFIX="mc_";get type(){return V.Media}get localStream(){return this._localStream}get remoteStream(){return this._remoteStream}constructor(e,n,t){super(e,n,t),this._localStream=this.options._stream,this.connectionId=this.options.connectionId||le.ID_PREFIX+N.randomToken(),this._negotiator=new Dn(this),this._localStream&&this._negotiator.startConnection({_stream:this._localStream,originator:!0})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this.emit("willCloseOnRemote")},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}addStream(e){p.log("Receiving stream",e),this._remoteStream=e,super.emit("stream",e)}handleMessage(e){const n=e.type,t=e.payload;switch(e.type){case L.Answer:this._negotiator.handleSDP(n,t.sdp),this._open=!0;break;case L.Candidate:this._negotiator.handleCandidate(t.candidate);break;default:p.warn(`Unrecognized message type:${n} from peer:${this.peer}`);break}}answer(e,n={}){if(this._localStream){p.warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");return}this._localStream=e,n&&n.sdpTransform&&(this.options.sdpTransform=n.sdpTransform),this._negotiator.startConnection({...this.options._payload,_stream:e});const t=this.provider._getMessages(this.connectionId);for(const i of t)this.handleMessage(i);this._open=!0}close(){this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this._localStream=null,this._remoteStream=null,this.provider&&(this.provider._removeConnection(this),this.provider=null),this.options&&this.options._stream&&(this.options._stream=null),this.open&&(this._open=!1,super.emit("close"))}}class cr{constructor(e){this._options=e}_buildRequest(e){const n=this._options.secure?"https":"http",{host:t,port:i,path:s,key:o}=this._options,a=new URL(`${n}://${t}:${i}${s}${o}/${e}`);return a.searchParams.set("ts",`${Date.now()}${Math.random()}`),a.searchParams.set("version",In),fetch(a.href,{referrerPolicy:this._options.referrerPolicy})}async retrieveId(){try{const e=await this._buildRequest("id");if(e.status!==200)throw new Error(`Error. Status:${e.status}`);return e.text()}catch(e){p.error("Error retrieving ID",e);let n="";throw this._options.path==="/"&&this._options.host!==N.CLOUD_HOST&&(n=" If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer."),new Error("Could not get an ID from the server."+n)}}async listAllPeers(){try{const e=await this._buildRequest("peers");if(e.status!==200){if(e.status===401){let n="";throw this._options.host===N.CLOUD_HOST?n="It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.":n="You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.",new Error("It doesn't look like you have permission to list peers IDs. "+n)}throw new Error(`Error. Status:${e.status}`)}return e.json()}catch(e){throw p.error("Error retrieving list peers",e),new Error("Could not get list peers from the server."+e)}}}class de extends An{static#e=this.ID_PREFIX="dc_";static#t=this.MAX_BUFFERED_AMOUNT=8388608;get type(){return V.Data}constructor(e,n,t){super(e,n,t),this.connectionId=this.options.connectionId||de.ID_PREFIX+En(),this.label=this.options.label||this.connectionId,this.reliable=!!this.options.reliable,this._negotiator=new Dn(this),this._negotiator.startConnection(this.options._payload||{originator:!0,reliable:this.reliable})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this._open=!0,this.emit("open")},this.dataChannel.onmessage=n=>{p.log(`DC#${this.connectionId} dc onmessage:`,n.data)},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}close(e){if(e?.flush){this.send({__peerData:{type:"close"}});return}this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this.provider&&(this.provider._removeConnection(this),this.provider=null),this.dataChannel&&(this.dataChannel.onopen=null,this.dataChannel.onmessage=null,this.dataChannel.onclose=null,this.dataChannel=null),this.open&&(this._open=!1,super.emit("close"))}send(e,n=!1){if(!this.open){this.emitError(et.NotOpenYet,"Connection is not open. You should listen for the `open` event before sending messages.");return}return this._send(e,n)}async handleMessage(e){const n=e.payload;switch(e.type){case L.Answer:await this._negotiator.handleSDP(e.type,n.sdp);break;case L.Candidate:await this._negotiator.handleCandidate(n.candidate);break;default:p.warn("Unrecognized message type:",e.type,"from peer:",this.peer);break}}}class tt extends de{get bufferSize(){return this._bufferSize}_initializeDataChannel(e){super._initializeDataChannel(e),this.dataChannel.binaryType="arraybuffer",this.dataChannel.addEventListener("message",n=>this._handleDataMessage(n))}_bufferedSend(e){(this._buffering||!this._trySend(e))&&(this._buffer.push(e),this._bufferSize=this._buffer.length)}_trySend(e){if(!this.open)return!1;if(this.dataChannel.bufferedAmount>de.MAX_BUFFERED_AMOUNT)return this._buffering=!0,setTimeout(()=>{this._buffering=!1,this._tryBuffer()},50),!1;try{this.dataChannel.send(e)}catch(n){return p.error(`DC#:${this.connectionId} Error when sending:`,n),this._buffering=!0,this.close(),!1}return!0}_tryBuffer(){if(!this.open||this._buffer.length===0)return;const e=this._buffer[0];this._trySend(e)&&(this._buffer.shift(),this._bufferSize=this._buffer.length,this._tryBuffer())}close(e){if(e?.flush){this.send({__peerData:{type:"close"}});return}this._buffer=[],this._bufferSize=0,super.close()}constructor(...e){super(...e),this._buffer=[],this._bufferSize=0,this._buffering=!1}}class ve extends tt{close(e){super.close(e),this._chunkedData={}}constructor(e,n,t){super(e,n,t),this.chunker=new kn,this.serialization=pe.Binary,this._chunkedData={}}_handleDataMessage({data:e}){const n=qt(e),t=n.__peerData;if(t){if(t.type==="close"){this.close();return}this._handleChunk(n);return}this.emit("data",n)}_handleChunk(e){const n=e.__peerData,t=this._chunkedData[n]||{data:[],count:0,total:e.total};if(t.data[e.n]=new Uint8Array(e.data),t.count++,this._chunkedData[n]=t,t.total===t.count){delete this._chunkedData[n];const i=Zn(t.data);this._handleDataMessage({data:i})}}_send(e,n){const t=Jt(e);if(t instanceof Promise)return this._send_blob(t);if(!n&&t.byteLength>this.chunker.chunkedMTU){this._sendChunks(t);return}this._bufferedSend(t)}async _send_blob(e){const n=await e;if(n.byteLength>this.chunker.chunkedMTU){this._sendChunks(n);return}this._bufferedSend(n)}_sendChunks(e){const n=this.chunker.chunk(e);p.log(`DC#${this.connectionId} Try to send ${n.length} chunks...`);for(const t of n)this.send(t,!0)}}class fr extends tt{_handleDataMessage({data:e}){super.emit("data",e)}_send(e,n){this._bufferedSend(e)}constructor(...e){super(...e),this.serialization=pe.None}}class ur extends tt{_handleDataMessage({data:e}){const n=this.parse(this.decoder.decode(e)),t=n.__peerData;if(t&&t.type==="close"){this.close();return}this.emit("data",n)}_send(e,n){const t=this.encoder.encode(this.stringify(e));if(t.byteLength>=N.chunkedMTU){this.emitError(et.MessageToBig,"Message too big for JSON channel");return}this._bufferedSend(t)}constructor(...e){super(...e),this.serialization=pe.JSON,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.stringify=JSON.stringify,this.parse=JSON.parse}}class nt extends Mn{static#e=this.DEFAULT_KEY="peerjs";get id(){return this._id}get options(){return this._options}get open(){return this._open}get socket(){return this._socket}get connections(){const e=Object.create(null);for(const[n,t]of this._connections)e[n]=t;return e}get destroyed(){return this._destroyed}get disconnected(){return this._disconnected}constructor(e,n){super(),this._serializers={raw:fr,json:ur,binary:ve,"binary-utf8":ve,default:ve},this._id=null,this._lastServerId=null,this._destroyed=!1,this._disconnected=!1,this._open=!1,this._connections=new Map,this._lostMessages=new Map;let t;if(e&&e.constructor==Object?n=e:e&&(t=e.toString()),n={debug:0,host:N.CLOUD_HOST,port:N.CLOUD_PORT,path:"/",key:nt.DEFAULT_KEY,token:N.randomToken(),config:N.defaultConfig,referrerPolicy:"strict-origin-when-cross-origin",serializers:{},...n},this._options=n,this._serializers={...this._serializers,...this.options.serializers},this._options.host==="/"&&(this._options.host=window.location.hostname),this._options.path&&(this._options.path[0]!=="/"&&(this._options.path="/"+this._options.path),this._options.path[this._options.path.length-1]!=="/"&&(this._options.path+="/")),this._options.secure===void 0&&this._options.host!==N.CLOUD_HOST?this._options.secure=N.isSecure():this._options.host==N.CLOUD_HOST&&(this._options.secure=!0),this._options.logFunction&&p.setLogFunction(this._options.logFunction),p.logLevel=this._options.debug||0,this._api=new cr(n),this._socket=this._createServerConnection(),!N.supports.audioVideo&&!N.supports.data){this._delayedAbort(D.BrowserIncompatible,"The current browser does not support WebRTC");return}if(t&&!N.validateId(t)){this._delayedAbort(D.InvalidID,`ID "${t}" is invalid`);return}t?this._initialize(t):this._api.retrieveId().then(i=>this._initialize(i)).catch(i=>this._abort(D.ServerError,i))}_createServerConnection(){const e=new or(this._options.secure,this._options.host,this._options.port,this._options.path,this._options.key,this._options.pingInterval);return e.on(w.Message,n=>{this._handleMessage(n)}),e.on(w.Error,n=>{this._abort(D.SocketError,n)}),e.on(w.Disconnected,()=>{this.disconnected||(this.emitError(D.Network,"Lost connection to server."),this.disconnect())}),e.on(w.Close,()=>{this.disconnected||this._abort(D.SocketClosed,"Underlying socket is already closed.")}),e}_initialize(e){this._id=e,this.socket.start(e,this._options.token)}_handleMessage(e){const n=e.type,t=e.payload,i=e.src;switch(n){case L.Open:this._lastServerId=this.id,this._open=!0,this.emit("open",this.id);break;case L.Error:this._abort(D.ServerError,t.msg);break;case L.IdTaken:this._abort(D.UnavailableID,`ID "${this.id}" is taken`);break;case L.InvalidKey:this._abort(D.InvalidKey,`API KEY "${this._options.key}" is invalid`);break;case L.Leave:p.log(`Received leave message from ${i}`),this._cleanupPeer(i),this._connections.delete(i);break;case L.Expire:this.emitError(D.PeerUnavailable,`Could not connect to peer ${i}`);break;case L.Offer:{const s=t.connectionId;let o=this.getConnection(i,s);if(o&&(o.close(),p.warn(`Offer received for existing Connection ID:${s}`)),t.type===V.Media){const c=new le(i,this,{connectionId:s,_payload:t,metadata:t.metadata});o=c,this._addConnection(i,o),this.emit("call",c)}else if(t.type===V.Data){const c=new this._serializers[t.serialization](i,this,{connectionId:s,_payload:t,metadata:t.metadata,label:t.label,serialization:t.serialization,reliable:t.reliable});o=c,this._addConnection(i,o),this.emit("connection",c)}else{p.warn(`Received malformed connection type:${t.type}`);return}const a=this._getMessages(s);for(const c of a)o.handleMessage(c);break}default:{if(!t){p.warn(`You received a malformed message from ${i} of type ${n}`);return}const s=t.connectionId,o=this.getConnection(i,s);o&&o.peerConnection?o.handleMessage(e):s?this._storeMessage(s,e):p.warn("You received an unrecognized message:",e);break}}}_storeMessage(e,n){this._lostMessages.has(e)||this._lostMessages.set(e,[]),this._lostMessages.get(e).push(n)}_getMessages(e){const n=this._lostMessages.get(e);return n?(this._lostMessages.delete(e),n):[]}connect(e,n={}){if(n={serialization:"default",...n},this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available."),this.emitError(D.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}const t=new this._serializers[n.serialization](e,this,n);return this._addConnection(e,t),t}call(e,n,t={}){if(this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect."),this.emitError(D.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}if(!n){p.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}const i=new le(e,this,{...t,_stream:n});return this._addConnection(e,i),i}_addConnection(e,n){p.log(`add connection ${n.type}:${n.connectionId} to peerId:${e}`),this._connections.has(e)||this._connections.set(e,[]),this._connections.get(e).push(n)}_removeConnection(e){const n=this._connections.get(e.peer);if(n){const t=n.indexOf(e);t!==-1&&n.splice(t,1)}this._lostMessages.delete(e.connectionId)}getConnection(e,n){const t=this._connections.get(e);if(!t)return null;for(const i of t)if(i.connectionId===n)return i;return null}_delayedAbort(e,n){setTimeout(()=>{this._abort(e,n)},0)}_abort(e,n){p.error("Aborting!"),this.emitError(e,n),this._lastServerId?this.disconnect():this.destroy()}destroy(){this.destroyed||(p.log(`Destroy peer with ID:${this.id}`),this.disconnect(),this._cleanup(),this._destroyed=!0,this.emit("close"))}_cleanup(){for(const e of this._connections.keys())this._cleanupPeer(e),this._connections.delete(e);this.socket.removeAllListeners()}_cleanupPeer(e){const n=this._connections.get(e);if(n)for(const t of n)t.close()}disconnect(){if(this.disconnected)return;const e=this.id;p.log(`Disconnect peer with ID:${e}`),this._disconnected=!0,this._open=!1,this.socket.close(),this._lastServerId=e,this._id=null,this.emit("disconnected",e)}reconnect(){if(this.disconnected&&!this.destroyed)p.log(`Attempting reconnection to server with ID ${this._lastServerId}`),this._disconnected=!1,this._initialize(this._lastServerId);else{if(this.destroyed)throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");if(!this.disconnected&&!this.open)p.error("In a hurry? We're still trying to make the initial connection!");else throw new Error(`Peer ${this.id} cannot reconnect because it is not disconnected from the server!`)}}listAllPeers(e=n=>{}){this._api.listAllPeers().then(n=>e(n)).catch(n=>this._abort(D.ServerError,n))}}var he=nt;class lr{constructor(e){this._playerId=null,this._dataConnection=null,this._peer=e?new he(e):new he,this._ownIdPromise=new Promise((n,t)=>{const i=setTimeout(()=>t(new Error("Peer ID not assigned in time")),1e4);this._peer.on("open",s=>{clearTimeout(i),this._playerId=s,n(s)}),this._peer.on("error",s=>{clearTimeout(i),t(s)})}),this._peer.on("error",n=>{console.error("PeerJS error:",n.type,n.message)}),window.addEventListener("beforeunload",()=>{if(this._dataConnection?.open&&this._playerId!==null){const n={playerId:this._playerId,action:"LEAVE",timestamp:Date.now()};try{this._dataConnection.send(n)}catch(t){console.warn("Failed to send LEAVE:",t)}}this._dataConnection?.close(),this._peer.destroy()})}async joinMatch(){const n=new URLSearchParams(window.location.search).get("hostPeerId");if(!n)throw new Error("No hostPeerId found in URL parameters.");const t=this._peer.connect(n,{reliable:!1});this._dataConnection=t,await new Promise((i,s)=>{const o=setTimeout(()=>{t.close(),s(new Error("Connection timeout"))},15e3);t.on("open",()=>{if(clearTimeout(o),this._playerId){const a={playerId:this._playerId,action:"JOIN",timestamp:Date.now()};t.send(a),console.log("JOIN sent, data connection open"),i()}else this._ownIdPromise.then(a=>{const c={playerId:a,action:"JOIN",timestamp:Date.now()};t.send(c),console.log("JOIN sent, data connection open"),i()}).catch(s)}),t.on("error",a=>{clearTimeout(o),s(a)})}),t.on("data",i=>{console.log("Received from host:",i)}),t.on("close",()=>{console.log("Data connection closed by host"),this._dataConnection=null})}async sendMove(e){if(this._dataConnection?.open){if(this._playerId===null)throw new Error("Player ID is not set. Cannot send data.");const n={playerId:this._playerId,action:"MOVE",button:e,timestamp:Date.now()};this._dataConnection.send(n)}else console.warn("Data connection is not open. Cannot send move.")}get isConnected(){return!!this._dataConnection?.open}destroy(){this._dataConnection?.close(),this._peer.destroy()}}var Q={},Se,mt;function dr(){return mt||(mt=1,Se=function(){return typeof Promise=="function"&&Promise.prototype&&Promise.prototype.then}),Se}var Te={},z={},yt;function H(){if(yt)return z;yt=1;let r;const e=[0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706];return z.getSymbolSize=function(t){if(!t)throw new Error('"version" cannot be null or undefined');if(t<1||t>40)throw new Error('"version" should be in range from 1 to 40');return t*4+17},z.getSymbolTotalCodewords=function(t){return e[t]},z.getBCHDigit=function(n){let t=0;for(;n!==0;)t++,n>>>=1;return t},z.setToSJISFunction=function(t){if(typeof t!="function")throw new Error('"toSJISFunc" is not a valid function.');r=t},z.isKanjiModeEnabled=function(){return typeof r<"u"},z.toSJIS=function(t){return r(t)},z}var Re={},_t;function rt(){return _t||(_t=1,(function(r){r.L={bit:1},r.M={bit:0},r.Q={bit:3},r.H={bit:2};function e(n){if(typeof n!="string")throw new Error("Param is not a string");switch(n.toLowerCase()){case"l":case"low":return r.L;case"m":case"medium":return r.M;case"q":case"quartile":return r.Q;case"h":case"high":return r.H;default:throw new Error("Unknown EC Level: "+n)}}r.isValid=function(t){return t&&typeof t.bit<"u"&&t.bit>=0&&t.bit<4},r.from=function(t,i){if(r.isValid(t))return t;try{return e(t)}catch{return i}}})(Re)),Re}var Pe,Ct;function hr(){if(Ct)return Pe;Ct=1;function r(){this.buffer=[],this.length=0}return r.prototype={get:function(e){const n=Math.floor(e/8);return(this.buffer[n]>>>7-e%8&1)===1},put:function(e,n){for(let t=0;t<n;t++)this.putBit((e>>>n-t-1&1)===1)},getLengthInBits:function(){return this.length},putBit:function(e){const n=Math.floor(this.length/8);this.buffer.length<=n&&this.buffer.push(0),e&&(this.buffer[n]|=128>>>this.length%8),this.length++}},Pe=r,Pe}var ke,bt;function pr(){if(bt)return ke;bt=1;function r(e){if(!e||e<1)throw new Error("BitMatrix size must be defined and greater than 0");this.size=e,this.data=new Uint8Array(e*e),this.reservedBit=new Uint8Array(e*e)}return r.prototype.set=function(e,n,t,i){const s=e*this.size+n;this.data[s]=t,i&&(this.reservedBit[s]=!0)},r.prototype.get=function(e,n){return this.data[e*this.size+n]},r.prototype.xor=function(e,n,t){this.data[e*this.size+n]^=t},r.prototype.isReserved=function(e,n){return this.reservedBit[e*this.size+n]},ke=r,ke}var Ee={},vt;function gr(){return vt||(vt=1,(function(r){const e=H().getSymbolSize;r.getRowColCoords=function(t){if(t===1)return[];const i=Math.floor(t/7)+2,s=e(t),o=s===145?26:Math.ceil((s-13)/(2*i-2))*2,a=[s-7];for(let c=1;c<i-1;c++)a[c]=a[c-1]-o;return a.push(6),a.reverse()},r.getPositions=function(t){const i=[],s=r.getRowColCoords(t),o=s.length;for(let a=0;a<o;a++)for(let c=0;c<o;c++)a===0&&c===0||a===0&&c===o-1||a===o-1&&c===0||i.push([s[a],s[c]]);return i}})(Ee)),Ee}var xe={},St;function mr(){if(St)return xe;St=1;const r=H().getSymbolSize,e=7;return xe.getPositions=function(t){const i=r(t);return[[0,0],[i-e,0],[0,i-e]]},xe}var Ie={},Tt;function yr(){return Tt||(Tt=1,(function(r){r.Patterns={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};const e={N1:3,N2:3,N3:40,N4:10};r.isValid=function(i){return i!=null&&i!==""&&!isNaN(i)&&i>=0&&i<=7},r.from=function(i){return r.isValid(i)?parseInt(i,10):void 0},r.getPenaltyN1=function(i){const s=i.size;let o=0,a=0,c=0,f=null,u=null;for(let l=0;l<s;l++){a=c=0,f=u=null;for(let d=0;d<s;d++){let h=i.get(l,d);h===f?a++:(a>=5&&(o+=e.N1+(a-5)),f=h,a=1),h=i.get(d,l),h===u?c++:(c>=5&&(o+=e.N1+(c-5)),u=h,c=1)}a>=5&&(o+=e.N1+(a-5)),c>=5&&(o+=e.N1+(c-5))}return o},r.getPenaltyN2=function(i){const s=i.size;let o=0;for(let a=0;a<s-1;a++)for(let c=0;c<s-1;c++){const f=i.get(a,c)+i.get(a,c+1)+i.get(a+1,c)+i.get(a+1,c+1);(f===4||f===0)&&o++}return o*e.N2},r.getPenaltyN3=function(i){const s=i.size;let o=0,a=0,c=0;for(let f=0;f<s;f++){a=c=0;for(let u=0;u<s;u++)a=a<<1&2047|i.get(f,u),u>=10&&(a===1488||a===93)&&o++,c=c<<1&2047|i.get(u,f),u>=10&&(c===1488||c===93)&&o++}return o*e.N3},r.getPenaltyN4=function(i){let s=0;const o=i.data.length;for(let c=0;c<o;c++)s+=i.data[c];return Math.abs(Math.ceil(s*100/o/5)-10)*e.N4};function n(t,i,s){switch(t){case r.Patterns.PATTERN000:return(i+s)%2===0;case r.Patterns.PATTERN001:return i%2===0;case r.Patterns.PATTERN010:return s%3===0;case r.Patterns.PATTERN011:return(i+s)%3===0;case r.Patterns.PATTERN100:return(Math.floor(i/2)+Math.floor(s/3))%2===0;case r.Patterns.PATTERN101:return i*s%2+i*s%3===0;case r.Patterns.PATTERN110:return(i*s%2+i*s%3)%2===0;case r.Patterns.PATTERN111:return(i*s%3+(i+s)%2)%2===0;default:throw new Error("bad maskPattern:"+t)}}r.applyMask=function(i,s){const o=s.size;for(let a=0;a<o;a++)for(let c=0;c<o;c++)s.isReserved(c,a)||s.xor(c,a,n(i,c,a))},r.getBestMask=function(i,s){const o=Object.keys(r.Patterns).length;let a=0,c=1/0;for(let f=0;f<o;f++){s(f),r.applyMask(f,i);const u=r.getPenaltyN1(i)+r.getPenaltyN2(i)+r.getPenaltyN3(i)+r.getPenaltyN4(i);r.applyMask(f,i),u<c&&(c=u,a=f)}return a}})(Ie)),Ie}var ie={},Rt;function Ln(){if(Rt)return ie;Rt=1;const r=rt(),e=[1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,4,1,2,4,4,2,4,4,4,2,4,6,5,2,4,6,6,2,5,8,8,4,5,8,8,4,5,8,11,4,8,10,11,4,9,12,16,4,9,16,16,6,10,12,18,6,10,17,16,6,11,16,19,6,13,18,21,7,14,21,25,8,16,20,25,8,17,23,25,9,17,23,34,9,18,25,30,10,20,27,32,12,21,29,35,12,23,34,37,12,25,34,40,13,26,35,42,14,28,38,45,15,29,40,48,16,31,43,51,17,33,45,54,18,35,48,57,19,37,51,60,19,38,53,63,20,40,56,66,21,43,59,70,22,45,62,74,24,47,65,77,25,49,68,81],n=[7,10,13,17,10,16,22,28,15,26,36,44,20,36,52,64,26,48,72,88,36,64,96,112,40,72,108,130,48,88,132,156,60,110,160,192,72,130,192,224,80,150,224,264,96,176,260,308,104,198,288,352,120,216,320,384,132,240,360,432,144,280,408,480,168,308,448,532,180,338,504,588,196,364,546,650,224,416,600,700,224,442,644,750,252,476,690,816,270,504,750,900,300,560,810,960,312,588,870,1050,336,644,952,1110,360,700,1020,1200,390,728,1050,1260,420,784,1140,1350,450,812,1200,1440,480,868,1290,1530,510,924,1350,1620,540,980,1440,1710,570,1036,1530,1800,570,1064,1590,1890,600,1120,1680,1980,630,1204,1770,2100,660,1260,1860,2220,720,1316,1950,2310,750,1372,2040,2430];return ie.getBlocksCount=function(i,s){switch(s){case r.L:return e[(i-1)*4+0];case r.M:return e[(i-1)*4+1];case r.Q:return e[(i-1)*4+2];case r.H:return e[(i-1)*4+3];default:return}},ie.getTotalCodewordsCount=function(i,s){switch(s){case r.L:return n[(i-1)*4+0];case r.M:return n[(i-1)*4+1];case r.Q:return n[(i-1)*4+2];case r.H:return n[(i-1)*4+3];default:return}},ie}var De={},ee={},Pt;function _r(){if(Pt)return ee;Pt=1;const r=new Uint8Array(512),e=new Uint8Array(256);return(function(){let t=1;for(let i=0;i<255;i++)r[i]=t,e[t]=i,t<<=1,t&256&&(t^=285);for(let i=255;i<512;i++)r[i]=r[i-255]})(),ee.log=function(t){if(t<1)throw new Error("log("+t+")");return e[t]},ee.exp=function(t){return r[t]},ee.mul=function(t,i){return t===0||i===0?0:r[e[t]+e[i]]},ee}var kt;function Cr(){return kt||(kt=1,(function(r){const e=_r();r.mul=function(t,i){const s=new Uint8Array(t.length+i.length-1);for(let o=0;o<t.length;o++)for(let a=0;a<i.length;a++)s[o+a]^=e.mul(t[o],i[a]);return s},r.mod=function(t,i){let s=new Uint8Array(t);for(;s.length-i.length>=0;){const o=s[0];for(let c=0;c<i.length;c++)s[c]^=e.mul(i[c],o);let a=0;for(;a<s.length&&s[a]===0;)a++;s=s.slice(a)}return s},r.generateECPolynomial=function(t){let i=new Uint8Array([1]);for(let s=0;s<t;s++)i=r.mul(i,new Uint8Array([1,e.exp(s)]));return i}})(De)),De}var Me,Et;function br(){if(Et)return Me;Et=1;const r=Cr();function e(n){this.genPoly=void 0,this.degree=n,this.degree&&this.initialize(this.degree)}return e.prototype.initialize=function(t){this.degree=t,this.genPoly=r.generateECPolynomial(this.degree)},e.prototype.encode=function(t){if(!this.genPoly)throw new Error("Encoder not initialized");const i=new Uint8Array(t.length+this.degree);i.set(t);const s=r.mod(i,this.genPoly),o=this.degree-s.length;if(o>0){const a=new Uint8Array(this.degree);return a.set(s,o),a}return s},Me=e,Me}var Ae={},Le={},Be={},xt;function Bn(){return xt||(xt=1,Be.isValid=function(e){return!isNaN(e)&&e>=1&&e<=40}),Be}var U={},It;function On(){if(It)return U;It=1;const r="[0-9]+",e="[A-Z $%*+\\-./:]+";let n="(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";n=n.replace(/u/g,"\\u");const t="(?:(?![A-Z0-9 $%*+\\-./:]|"+n+`)(?:.|[\r
|
|
41
|
+
isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`}constructor(){this.isIOS=typeof navigator<"u"?["iPad","iPhone","iPod"].includes(navigator.platform):!1,this.supportedBrowsers=["firefox","chrome","safari"],this.minFirefoxVersion=59,this.minChromeVersion=72,this.minSafariVersion=605}},er=r=>!r||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(r),En=()=>Math.random().toString(36).slice(2),gt={iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:["turn:eu-0.turn.peerjs.com:3478","turn:us-0.turn.peerjs.com:3478"],username:"peerjs",credential:"peerjsp"}],sdpSemantics:"unified-plan"};class tr extends kn{noop(){}blobToArrayBuffer(e,n){const t=new FileReader;return t.onload=function(i){i.target&&n(i.target.result)},t.readAsArrayBuffer(e),t}binaryStringToArrayBuffer(e){const n=new Uint8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t)&255;return n.buffer}isSecure(){return location.protocol==="https:"}constructor(...e){super(...e),this.CLOUD_HOST="0.peerjs.com",this.CLOUD_PORT=443,this.chunkedBrowsers={Chrome:1,chrome:1},this.defaultConfig=gt,this.browser=Z.getBrowser(),this.browserVersion=Z.getVersion(),this.pack=Jt,this.unpack=qt,this.supports=(function(){const n={browser:Z.isBrowserSupported(),webRTC:Z.isWebRTCSupported(),audioVideo:!1,data:!1,binaryBlob:!1,reliable:!1};if(!n.webRTC)return n;let t;try{t=new RTCPeerConnection(gt),n.audioVideo=!0;let i;try{i=t.createDataChannel("_PEERJSTEST",{ordered:!0}),n.data=!0,n.reliable=!!i.ordered;try{i.binaryType="blob",n.binaryBlob=!Z.isIOS}catch{}}catch{}finally{i&&i.close()}}catch{}finally{t&&t.close()}return n})(),this.validateId=er,this.randomToken=En}}const N=new tr,nr="PeerJS: ";class rr{get logLevel(){return this._logLevel}set logLevel(e){this._logLevel=e}log(...e){this._logLevel>=3&&this._print(3,...e)}warn(...e){this._logLevel>=2&&this._print(2,...e)}error(...e){this._logLevel>=1&&this._print(1,...e)}setLogFunction(e){this._print=e}_print(e,...n){const t=[nr,...n];for(const i in t)t[i]instanceof Error&&(t[i]="("+t[i].name+") "+t[i].message);e>=3?console.log(...t):e>=2?console.warn("WARNING",...t):e>=1&&console.error("ERROR",...t)}constructor(){this._logLevel=0}}var p=new rr,Ze={},ir=Object.prototype.hasOwnProperty,O="~";function ne(){}Object.create&&(ne.prototype=Object.create(null),new ne().__proto__||(O=!1));function sr(r,e,n){this.fn=r,this.context=e,this.once=n||!1}function xn(r,e,n,t,i){if(typeof n!="function")throw new TypeError("The listener must be a function");var s=new sr(n,t||r,i),o=O?O+e:e;return r._events[o]?r._events[o].fn?r._events[o]=[r._events[o],s]:r._events[o].push(s):(r._events[o]=s,r._eventsCount++),r}function ue(r,e){--r._eventsCount===0?r._events=new ne:delete r._events[e]}function B(){this._events=new ne,this._eventsCount=0}B.prototype.eventNames=function(){var e=[],n,t;if(this._eventsCount===0)return e;for(t in n=this._events)ir.call(n,t)&&e.push(O?t.slice(1):t);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(n)):e};B.prototype.listeners=function(e){var n=O?O+e:e,t=this._events[n];if(!t)return[];if(t.fn)return[t.fn];for(var i=0,s=t.length,o=new Array(s);i<s;i++)o[i]=t[i].fn;return o};B.prototype.listenerCount=function(e){var n=O?O+e:e,t=this._events[n];return t?t.fn?1:t.length:0};B.prototype.emit=function(e,n,t,i,s,o){var a=O?O+e:e;if(!this._events[a])return!1;var c=this._events[a],f=arguments.length,u,l;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),f){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,n),!0;case 3:return c.fn.call(c.context,n,t),!0;case 4:return c.fn.call(c.context,n,t,i),!0;case 5:return c.fn.call(c.context,n,t,i,s),!0;case 6:return c.fn.call(c.context,n,t,i,s,o),!0}for(l=1,u=new Array(f-1);l<f;l++)u[l-1]=arguments[l];c.fn.apply(c.context,u)}else{var d=c.length,h;for(l=0;l<d;l++)switch(c[l].once&&this.removeListener(e,c[l].fn,void 0,!0),f){case 1:c[l].fn.call(c[l].context);break;case 2:c[l].fn.call(c[l].context,n);break;case 3:c[l].fn.call(c[l].context,n,t);break;case 4:c[l].fn.call(c[l].context,n,t,i);break;default:if(!u)for(h=1,u=new Array(f-1);h<f;h++)u[h-1]=arguments[h];c[l].fn.apply(c[l].context,u)}}return!0};B.prototype.on=function(e,n,t){return xn(this,e,n,t,!1)};B.prototype.once=function(e,n,t){return xn(this,e,n,t,!0)};B.prototype.removeListener=function(e,n,t,i){var s=O?O+e:e;if(!this._events[s])return this;if(!n)return ue(this,s),this;var o=this._events[s];if(o.fn)o.fn===n&&(!i||o.once)&&(!t||o.context===t)&&ue(this,s);else{for(var a=0,c=[],f=o.length;a<f;a++)(o[a].fn!==n||i&&!o[a].once||t&&o[a].context!==t)&&c.push(o[a]);c.length?this._events[s]=c.length===1?c[0]:c:ue(this,s)}return this};B.prototype.removeAllListeners=function(e){var n;return e?(n=O?O+e:e,this._events[n]&&ue(this,n)):(this._events=new ne,this._eventsCount=0),this};B.prototype.off=B.prototype.removeListener;B.prototype.addListener=B.prototype.on;B.prefixed=O;B.EventEmitter=B;Ze=B;var G={};J(G,"ConnectionType",()=>V);J(G,"PeerErrorType",()=>D);J(G,"BaseConnectionErrorType",()=>We);J(G,"DataConnectionErrorType",()=>et);J(G,"SerializationType",()=>pe);J(G,"SocketEventType",()=>w);J(G,"ServerMessageType",()=>L);var V=(function(r){return r.Data="data",r.Media="media",r})({}),D=(function(r){return r.BrowserIncompatible="browser-incompatible",r.Disconnected="disconnected",r.InvalidID="invalid-id",r.InvalidKey="invalid-key",r.Network="network",r.PeerUnavailable="peer-unavailable",r.SslUnavailable="ssl-unavailable",r.ServerError="server-error",r.SocketError="socket-error",r.SocketClosed="socket-closed",r.UnavailableID="unavailable-id",r.WebRTC="webrtc",r})({}),We=(function(r){return r.NegotiationFailed="negotiation-failed",r.ConnectionClosed="connection-closed",r})({}),et=(function(r){return r.NotOpenYet="not-open-yet",r.MessageToBig="message-too-big",r})({}),pe=(function(r){return r.Binary="binary",r.BinaryUTF8="binary-utf8",r.JSON="json",r.None="raw",r})({}),w=(function(r){return r.Message="message",r.Disconnected="disconnected",r.Error="error",r.Close="close",r})({}),L=(function(r){return r.Heartbeat="HEARTBEAT",r.Candidate="CANDIDATE",r.Offer="OFFER",r.Answer="ANSWER",r.Open="OPEN",r.Error="ERROR",r.IdTaken="ID-TAKEN",r.InvalidKey="INVALID-KEY",r.Leave="LEAVE",r.Expire="EXPIRE",r})({});const In="1.5.5";class or extends Ze.EventEmitter{constructor(e,n,t,i,s,o=5e3){super(),this.pingInterval=o,this._disconnected=!0,this._messagesQueue=[];const a=e?"wss://":"ws://";this._baseUrl=a+n+":"+t+i+"peerjs?key="+s}start(e,n){this._id=e;const t=`${this._baseUrl}&id=${e}&token=${n}`;this._socket||!this._disconnected||(this._socket=new WebSocket(t+"&version="+In),this._disconnected=!1,this._socket.onmessage=i=>{let s;try{s=JSON.parse(i.data),p.log("Server message received:",s)}catch{p.log("Invalid server message",i.data);return}this.emit(w.Message,s)},this._socket.onclose=i=>{this._disconnected||(p.log("Socket closed.",i),this._cleanup(),this._disconnected=!0,this.emit(w.Disconnected))},this._socket.onopen=()=>{this._disconnected||(this._sendQueuedMessages(),p.log("Socket open"),this._scheduleHeartbeat())})}_scheduleHeartbeat(){this._wsPingTimer=setTimeout(()=>{this._sendHeartbeat()},this.pingInterval)}_sendHeartbeat(){if(!this._wsOpen()){p.log("Cannot send heartbeat, because socket closed");return}const e=JSON.stringify({type:L.Heartbeat});this._socket.send(e),this._scheduleHeartbeat()}_wsOpen(){return!!this._socket&&this._socket.readyState===1}_sendQueuedMessages(){const e=[...this._messagesQueue];this._messagesQueue=[];for(const n of e)this.send(n)}send(e){if(this._disconnected)return;if(!this._id){this._messagesQueue.push(e);return}if(!e.type){this.emit(w.Error,"Invalid message");return}if(!this._wsOpen())return;const n=JSON.stringify(e);this._socket.send(n)}close(){this._disconnected||(this._cleanup(),this._disconnected=!0)}_cleanup(){this._socket&&(this._socket.onopen=this._socket.onmessage=this._socket.onclose=null,this._socket.close(),this._socket=void 0),clearTimeout(this._wsPingTimer)}}class Dn{constructor(e){this.connection=e}startConnection(e){const n=this._startPeerConnection();if(this.connection.peerConnection=n,this.connection.type===V.Media&&e._stream&&this._addTracksToConnection(e._stream,n),e.originator){const t=this.connection,i={ordered:!!e.reliable},s=n.createDataChannel(t.label,i);t._initializeDataChannel(s),this._makeOffer()}else this.handleSDP("OFFER",e.sdp)}_startPeerConnection(){p.log("Creating RTCPeerConnection.");const e=new RTCPeerConnection(this.connection.provider.options.config);return this._setupListeners(e),e}_setupListeners(e){const n=this.connection.peer,t=this.connection.connectionId,i=this.connection.type,s=this.connection.provider;p.log("Listening for ICE candidates."),e.onicecandidate=o=>{!o.candidate||!o.candidate.candidate||(p.log(`Received ICE candidates for ${n}:`,o.candidate),s.socket.send({type:L.Candidate,payload:{candidate:o.candidate,type:i,connectionId:t},dst:n}))},e.oniceconnectionstatechange=()=>{switch(e.iceConnectionState){case"failed":p.log("iceConnectionState is failed, closing connections to "+n),this.connection.emitError(We.NegotiationFailed,"Negotiation of connection to "+n+" failed."),this.connection.close();break;case"closed":p.log("iceConnectionState is closed, closing connections to "+n),this.connection.emitError(We.ConnectionClosed,"Connection to "+n+" closed."),this.connection.close();break;case"disconnected":p.log("iceConnectionState changed to disconnected on the connection with "+n);break;case"completed":e.onicecandidate=()=>{};break}this.connection.emit("iceStateChanged",e.iceConnectionState)},p.log("Listening for data channel"),e.ondatachannel=o=>{p.log("Received data channel");const a=o.channel;s.getConnection(n,t)._initializeDataChannel(a)},p.log("Listening for remote stream"),e.ontrack=o=>{p.log("Received remote stream");const a=o.streams[0],c=s.getConnection(n,t);if(c.type===V.Media){const f=c;this._addStreamToMediaConnection(a,f)}}}cleanup(){p.log("Cleaning up PeerConnection to "+this.connection.peer);const e=this.connection.peerConnection;if(!e)return;this.connection.peerConnection=null,e.onicecandidate=e.oniceconnectionstatechange=e.ondatachannel=e.ontrack=()=>{};const n=e.signalingState!=="closed";let t=!1;const i=this.connection.dataChannel;i&&(t=!!i.readyState&&i.readyState!=="closed"),(n||t)&&e.close()}async _makeOffer(){const e=this.connection.peerConnection,n=this.connection.provider;try{const t=await e.createOffer(this.connection.options.constraints);p.log("Created offer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(t.sdp=this.connection.options.sdpTransform(t.sdp)||t.sdp);try{await e.setLocalDescription(t),p.log("Set localDescription:",t,`for:${this.connection.peer}`);let i={sdp:t,type:this.connection.type,connectionId:this.connection.connectionId,metadata:this.connection.metadata};if(this.connection.type===V.Data){const s=this.connection;i={...i,label:s.label,reliable:s.reliable,serialization:s.serialization}}n.socket.send({type:L.Offer,payload:i,dst:this.connection.peer})}catch(i){i!="OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"&&(n.emitError(D.WebRTC,i),p.log("Failed to setLocalDescription, ",i))}}catch(t){n.emitError(D.WebRTC,t),p.log("Failed to createOffer, ",t)}}async _makeAnswer(){const e=this.connection.peerConnection,n=this.connection.provider;try{const t=await e.createAnswer();p.log("Created answer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(t.sdp=this.connection.options.sdpTransform(t.sdp)||t.sdp);try{await e.setLocalDescription(t),p.log("Set localDescription:",t,`for:${this.connection.peer}`),n.socket.send({type:L.Answer,payload:{sdp:t,type:this.connection.type,connectionId:this.connection.connectionId},dst:this.connection.peer})}catch(i){n.emitError(D.WebRTC,i),p.log("Failed to setLocalDescription, ",i)}}catch(t){n.emitError(D.WebRTC,t),p.log("Failed to create answer, ",t)}}async handleSDP(e,n){n=new RTCSessionDescription(n);const t=this.connection.peerConnection,i=this.connection.provider;p.log("Setting remote description",n);const s=this;try{await t.setRemoteDescription(n),p.log(`Set remoteDescription:${e} for:${this.connection.peer}`),e==="OFFER"&&await s._makeAnswer()}catch(o){i.emitError(D.WebRTC,o),p.log("Failed to setRemoteDescription, ",o)}}async handleCandidate(e){p.log("handleCandidate:",e);try{await this.connection.peerConnection.addIceCandidate(e),p.log(`Added ICE candidate for:${this.connection.peer}`)}catch(n){this.connection.provider.emitError(D.WebRTC,n),p.log("Failed to handleCandidate, ",n)}}_addTracksToConnection(e,n){if(p.log(`add tracks from stream ${e.id} to peer connection`),!n.addTrack)return p.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");e.getTracks().forEach(t=>{n.addTrack(t,e)})}_addStreamToMediaConnection(e,n){p.log(`add stream ${e.id} to media connection ${n.connectionId}`),n.addStream(e)}}class Mn extends Ze.EventEmitter{emitError(e,n){p.error("Error:",n),this.emit("error",new ar(`${e}`,n))}}class ar extends Error{constructor(e,n){typeof n=="string"?super(n):(super(),Object.assign(this,n)),this.type=e}}class An extends Mn{get open(){return this._open}constructor(e,n,t){super(),this.peer=e,this.provider=n,this.options=t,this._open=!1,this.metadata=t.metadata}}class le extends An{static#e=this.ID_PREFIX="mc_";get type(){return V.Media}get localStream(){return this._localStream}get remoteStream(){return this._remoteStream}constructor(e,n,t){super(e,n,t),this._localStream=this.options._stream,this.connectionId=this.options.connectionId||le.ID_PREFIX+N.randomToken(),this._negotiator=new Dn(this),this._localStream&&this._negotiator.startConnection({_stream:this._localStream,originator:!0})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this.emit("willCloseOnRemote")},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}addStream(e){p.log("Receiving stream",e),this._remoteStream=e,super.emit("stream",e)}handleMessage(e){const n=e.type,t=e.payload;switch(e.type){case L.Answer:this._negotiator.handleSDP(n,t.sdp),this._open=!0;break;case L.Candidate:this._negotiator.handleCandidate(t.candidate);break;default:p.warn(`Unrecognized message type:${n} from peer:${this.peer}`);break}}answer(e,n={}){if(this._localStream){p.warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");return}this._localStream=e,n&&n.sdpTransform&&(this.options.sdpTransform=n.sdpTransform),this._negotiator.startConnection({...this.options._payload,_stream:e});const t=this.provider._getMessages(this.connectionId);for(const i of t)this.handleMessage(i);this._open=!0}close(){this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this._localStream=null,this._remoteStream=null,this.provider&&(this.provider._removeConnection(this),this.provider=null),this.options&&this.options._stream&&(this.options._stream=null),this.open&&(this._open=!1,super.emit("close"))}}class cr{constructor(e){this._options=e}_buildRequest(e){const n=this._options.secure?"https":"http",{host:t,port:i,path:s,key:o}=this._options,a=new URL(`${n}://${t}:${i}${s}${o}/${e}`);return a.searchParams.set("ts",`${Date.now()}${Math.random()}`),a.searchParams.set("version",In),fetch(a.href,{referrerPolicy:this._options.referrerPolicy})}async retrieveId(){try{const e=await this._buildRequest("id");if(e.status!==200)throw new Error(`Error. Status:${e.status}`);return e.text()}catch(e){p.error("Error retrieving ID",e);let n="";throw this._options.path==="/"&&this._options.host!==N.CLOUD_HOST&&(n=" If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer."),new Error("Could not get an ID from the server."+n)}}async listAllPeers(){try{const e=await this._buildRequest("peers");if(e.status!==200){if(e.status===401){let n="";throw this._options.host===N.CLOUD_HOST?n="It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.":n="You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.",new Error("It doesn't look like you have permission to list peers IDs. "+n)}throw new Error(`Error. Status:${e.status}`)}return e.json()}catch(e){throw p.error("Error retrieving list peers",e),new Error("Could not get list peers from the server."+e)}}}class de extends An{static#e=this.ID_PREFIX="dc_";static#t=this.MAX_BUFFERED_AMOUNT=8388608;get type(){return V.Data}constructor(e,n,t){super(e,n,t),this.connectionId=this.options.connectionId||de.ID_PREFIX+En(),this.label=this.options.label||this.connectionId,this.reliable=!!this.options.reliable,this._negotiator=new Dn(this),this._negotiator.startConnection(this.options._payload||{originator:!0,reliable:this.reliable})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this._open=!0,this.emit("open")},this.dataChannel.onmessage=n=>{p.log(`DC#${this.connectionId} dc onmessage:`,n.data)},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}close(e){if(e?.flush){this.send({__peerData:{type:"close"}});return}this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this.provider&&(this.provider._removeConnection(this),this.provider=null),this.dataChannel&&(this.dataChannel.onopen=null,this.dataChannel.onmessage=null,this.dataChannel.onclose=null,this.dataChannel=null),this.open&&(this._open=!1,super.emit("close"))}send(e,n=!1){if(!this.open){this.emitError(et.NotOpenYet,"Connection is not open. You should listen for the `open` event before sending messages.");return}return this._send(e,n)}async handleMessage(e){const n=e.payload;switch(e.type){case L.Answer:await this._negotiator.handleSDP(e.type,n.sdp);break;case L.Candidate:await this._negotiator.handleCandidate(n.candidate);break;default:p.warn("Unrecognized message type:",e.type,"from peer:",this.peer);break}}}class tt extends de{get bufferSize(){return this._bufferSize}_initializeDataChannel(e){super._initializeDataChannel(e),this.dataChannel.binaryType="arraybuffer",this.dataChannel.addEventListener("message",n=>this._handleDataMessage(n))}_bufferedSend(e){(this._buffering||!this._trySend(e))&&(this._buffer.push(e),this._bufferSize=this._buffer.length)}_trySend(e){if(!this.open)return!1;if(this.dataChannel.bufferedAmount>de.MAX_BUFFERED_AMOUNT)return this._buffering=!0,setTimeout(()=>{this._buffering=!1,this._tryBuffer()},50),!1;try{this.dataChannel.send(e)}catch(n){return p.error(`DC#:${this.connectionId} Error when sending:`,n),this._buffering=!0,this.close(),!1}return!0}_tryBuffer(){if(!this.open||this._buffer.length===0)return;const e=this._buffer[0];this._trySend(e)&&(this._buffer.shift(),this._bufferSize=this._buffer.length,this._tryBuffer())}close(e){if(e?.flush){this.send({__peerData:{type:"close"}});return}this._buffer=[],this._bufferSize=0,super.close()}constructor(...e){super(...e),this._buffer=[],this._bufferSize=0,this._buffering=!1}}class ve extends tt{close(e){super.close(e),this._chunkedData={}}constructor(e,n,t){super(e,n,t),this.chunker=new kn,this.serialization=pe.Binary,this._chunkedData={}}_handleDataMessage({data:e}){const n=qt(e),t=n.__peerData;if(t){if(t.type==="close"){this.close();return}this._handleChunk(n);return}this.emit("data",n)}_handleChunk(e){const n=e.__peerData,t=this._chunkedData[n]||{data:[],count:0,total:e.total};if(t.data[e.n]=new Uint8Array(e.data),t.count++,this._chunkedData[n]=t,t.total===t.count){delete this._chunkedData[n];const i=Zn(t.data);this._handleDataMessage({data:i})}}_send(e,n){const t=Jt(e);if(t instanceof Promise)return this._send_blob(t);if(!n&&t.byteLength>this.chunker.chunkedMTU){this._sendChunks(t);return}this._bufferedSend(t)}async _send_blob(e){const n=await e;if(n.byteLength>this.chunker.chunkedMTU){this._sendChunks(n);return}this._bufferedSend(n)}_sendChunks(e){const n=this.chunker.chunk(e);p.log(`DC#${this.connectionId} Try to send ${n.length} chunks...`);for(const t of n)this.send(t,!0)}}class fr extends tt{_handleDataMessage({data:e}){super.emit("data",e)}_send(e,n){this._bufferedSend(e)}constructor(...e){super(...e),this.serialization=pe.None}}class ur extends tt{_handleDataMessage({data:e}){const n=this.parse(this.decoder.decode(e)),t=n.__peerData;if(t&&t.type==="close"){this.close();return}this.emit("data",n)}_send(e,n){const t=this.encoder.encode(this.stringify(e));if(t.byteLength>=N.chunkedMTU){this.emitError(et.MessageToBig,"Message too big for JSON channel");return}this._bufferedSend(t)}constructor(...e){super(...e),this.serialization=pe.JSON,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.stringify=JSON.stringify,this.parse=JSON.parse}}class nt extends Mn{static#e=this.DEFAULT_KEY="peerjs";get id(){return this._id}get options(){return this._options}get open(){return this._open}get socket(){return this._socket}get connections(){const e=Object.create(null);for(const[n,t]of this._connections)e[n]=t;return e}get destroyed(){return this._destroyed}get disconnected(){return this._disconnected}constructor(e,n){super(),this._serializers={raw:fr,json:ur,binary:ve,"binary-utf8":ve,default:ve},this._id=null,this._lastServerId=null,this._destroyed=!1,this._disconnected=!1,this._open=!1,this._connections=new Map,this._lostMessages=new Map;let t;if(e&&e.constructor==Object?n=e:e&&(t=e.toString()),n={debug:0,host:N.CLOUD_HOST,port:N.CLOUD_PORT,path:"/",key:nt.DEFAULT_KEY,token:N.randomToken(),config:N.defaultConfig,referrerPolicy:"strict-origin-when-cross-origin",serializers:{},...n},this._options=n,this._serializers={...this._serializers,...this.options.serializers},this._options.host==="/"&&(this._options.host=window.location.hostname),this._options.path&&(this._options.path[0]!=="/"&&(this._options.path="/"+this._options.path),this._options.path[this._options.path.length-1]!=="/"&&(this._options.path+="/")),this._options.secure===void 0&&this._options.host!==N.CLOUD_HOST?this._options.secure=N.isSecure():this._options.host==N.CLOUD_HOST&&(this._options.secure=!0),this._options.logFunction&&p.setLogFunction(this._options.logFunction),p.logLevel=this._options.debug||0,this._api=new cr(n),this._socket=this._createServerConnection(),!N.supports.audioVideo&&!N.supports.data){this._delayedAbort(D.BrowserIncompatible,"The current browser does not support WebRTC");return}if(t&&!N.validateId(t)){this._delayedAbort(D.InvalidID,`ID "${t}" is invalid`);return}t?this._initialize(t):this._api.retrieveId().then(i=>this._initialize(i)).catch(i=>this._abort(D.ServerError,i))}_createServerConnection(){const e=new or(this._options.secure,this._options.host,this._options.port,this._options.path,this._options.key,this._options.pingInterval);return e.on(w.Message,n=>{this._handleMessage(n)}),e.on(w.Error,n=>{this._abort(D.SocketError,n)}),e.on(w.Disconnected,()=>{this.disconnected||(this.emitError(D.Network,"Lost connection to server."),this.disconnect())}),e.on(w.Close,()=>{this.disconnected||this._abort(D.SocketClosed,"Underlying socket is already closed.")}),e}_initialize(e){this._id=e,this.socket.start(e,this._options.token)}_handleMessage(e){const n=e.type,t=e.payload,i=e.src;switch(n){case L.Open:this._lastServerId=this.id,this._open=!0,this.emit("open",this.id);break;case L.Error:this._abort(D.ServerError,t.msg);break;case L.IdTaken:this._abort(D.UnavailableID,`ID "${this.id}" is taken`);break;case L.InvalidKey:this._abort(D.InvalidKey,`API KEY "${this._options.key}" is invalid`);break;case L.Leave:p.log(`Received leave message from ${i}`),this._cleanupPeer(i),this._connections.delete(i);break;case L.Expire:this.emitError(D.PeerUnavailable,`Could not connect to peer ${i}`);break;case L.Offer:{const s=t.connectionId;let o=this.getConnection(i,s);if(o&&(o.close(),p.warn(`Offer received for existing Connection ID:${s}`)),t.type===V.Media){const c=new le(i,this,{connectionId:s,_payload:t,metadata:t.metadata});o=c,this._addConnection(i,o),this.emit("call",c)}else if(t.type===V.Data){const c=new this._serializers[t.serialization](i,this,{connectionId:s,_payload:t,metadata:t.metadata,label:t.label,serialization:t.serialization,reliable:t.reliable});o=c,this._addConnection(i,o),this.emit("connection",c)}else{p.warn(`Received malformed connection type:${t.type}`);return}const a=this._getMessages(s);for(const c of a)o.handleMessage(c);break}default:{if(!t){p.warn(`You received a malformed message from ${i} of type ${n}`);return}const s=t.connectionId,o=this.getConnection(i,s);o&&o.peerConnection?o.handleMessage(e):s?this._storeMessage(s,e):p.warn("You received an unrecognized message:",e);break}}}_storeMessage(e,n){this._lostMessages.has(e)||this._lostMessages.set(e,[]),this._lostMessages.get(e).push(n)}_getMessages(e){const n=this._lostMessages.get(e);return n?(this._lostMessages.delete(e),n):[]}connect(e,n={}){if(n={serialization:"default",...n},this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available."),this.emitError(D.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}const t=new this._serializers[n.serialization](e,this,n);return this._addConnection(e,t),t}call(e,n,t={}){if(this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect."),this.emitError(D.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}if(!n){p.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}const i=new le(e,this,{...t,_stream:n});return this._addConnection(e,i),i}_addConnection(e,n){p.log(`add connection ${n.type}:${n.connectionId} to peerId:${e}`),this._connections.has(e)||this._connections.set(e,[]),this._connections.get(e).push(n)}_removeConnection(e){const n=this._connections.get(e.peer);if(n){const t=n.indexOf(e);t!==-1&&n.splice(t,1)}this._lostMessages.delete(e.connectionId)}getConnection(e,n){const t=this._connections.get(e);if(!t)return null;for(const i of t)if(i.connectionId===n)return i;return null}_delayedAbort(e,n){setTimeout(()=>{this._abort(e,n)},0)}_abort(e,n){p.error("Aborting!"),this.emitError(e,n),this._lastServerId?this.disconnect():this.destroy()}destroy(){this.destroyed||(p.log(`Destroy peer with ID:${this.id}`),this.disconnect(),this._cleanup(),this._destroyed=!0,this.emit("close"))}_cleanup(){for(const e of this._connections.keys())this._cleanupPeer(e),this._connections.delete(e);this.socket.removeAllListeners()}_cleanupPeer(e){const n=this._connections.get(e);if(n)for(const t of n)t.close()}disconnect(){if(this.disconnected)return;const e=this.id;p.log(`Disconnect peer with ID:${e}`),this._disconnected=!0,this._open=!1,this.socket.close(),this._lastServerId=e,this._id=null,this.emit("disconnected",e)}reconnect(){if(this.disconnected&&!this.destroyed)p.log(`Attempting reconnection to server with ID ${this._lastServerId}`),this._disconnected=!1,this._initialize(this._lastServerId);else{if(this.destroyed)throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");if(!this.disconnected&&!this.open)p.error("In a hurry? We're still trying to make the initial connection!");else throw new Error(`Peer ${this.id} cannot reconnect because it is not disconnected from the server!`)}}listAllPeers(e=n=>{}){this._api.listAllPeers().then(n=>e(n)).catch(n=>this._abort(D.ServerError,n))}}var he=nt;class lr{constructor(e){this._playerId=null,this._dataConnection=null,this._playerName=null,this._peer=e?new he(e):new he,this._ownIdPromise=new Promise((n,t)=>{const i=setTimeout(()=>t(new Error("Peer ID not assigned in time")),1e4);this._peer.on("open",s=>{clearTimeout(i),this._playerId=s,n(s)}),this._peer.on("error",s=>{clearTimeout(i),t(s)})}),this._peer.on("error",n=>{console.error("PeerJS error:",n.type,n.message)}),window.addEventListener("beforeunload",()=>{if(this._dataConnection?.open&&this._playerId!==null){const n={playerId:this._playerId,action:"LEAVE",playerName:this._playerName||"",timestamp:Date.now()};try{this._dataConnection.send(n)}catch(t){console.warn("Failed to send LEAVE:",t)}}this._dataConnection?.close(),this._peer.destroy()})}async joinMatch(e){this._playerName=e;const t=new URLSearchParams(window.location.search).get("hostPeerId");if(!t)throw new Error("No hostPeerId found in URL parameters.");const i=this._peer.connect(t,{reliable:!1});this._dataConnection=i,await new Promise((s,o)=>{const a=setTimeout(()=>{i.close(),o(new Error("Connection timeout"))},15e3);i.on("open",()=>{if(clearTimeout(a),this._playerId){const c={playerId:this._playerId,action:"JOIN",playerName:this._playerName||"",timestamp:Date.now()};i.send(c),console.log("JOIN sent, data connection open"),s()}else this._ownIdPromise.then(c=>{const f={playerId:c,action:"JOIN",playerName:this._playerName||"",timestamp:Date.now()};i.send(f),console.log("JOIN sent, data connection open"),s()}).catch(o)}),i.on("error",c=>{clearTimeout(a),o(c)})}),i.on("data",s=>{console.log("Received from host:",s)}),i.on("close",()=>{console.log("Data connection closed by host"),this._dataConnection=null})}async sendMove(e){if(this._dataConnection?.open){if(this._playerId===null||this._playerName===null)throw new Error("Player ID or Player Name is not set. Cannot send data.");const n={playerId:this._playerId,action:"MOVE",playerName:this._playerName,button:e,timestamp:Date.now()};this._dataConnection.send(n)}else console.warn("Data connection is not open. Cannot send move.")}get isConnected(){return!!this._dataConnection?.open}destroy(){this._dataConnection?.close(),this._peer.destroy()}}var Q={},Se,mt;function dr(){return mt||(mt=1,Se=function(){return typeof Promise=="function"&&Promise.prototype&&Promise.prototype.then}),Se}var Te={},z={},yt;function H(){if(yt)return z;yt=1;let r;const e=[0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706];return z.getSymbolSize=function(t){if(!t)throw new Error('"version" cannot be null or undefined');if(t<1||t>40)throw new Error('"version" should be in range from 1 to 40');return t*4+17},z.getSymbolTotalCodewords=function(t){return e[t]},z.getBCHDigit=function(n){let t=0;for(;n!==0;)t++,n>>>=1;return t},z.setToSJISFunction=function(t){if(typeof t!="function")throw new Error('"toSJISFunc" is not a valid function.');r=t},z.isKanjiModeEnabled=function(){return typeof r<"u"},z.toSJIS=function(t){return r(t)},z}var Re={},_t;function rt(){return _t||(_t=1,(function(r){r.L={bit:1},r.M={bit:0},r.Q={bit:3},r.H={bit:2};function e(n){if(typeof n!="string")throw new Error("Param is not a string");switch(n.toLowerCase()){case"l":case"low":return r.L;case"m":case"medium":return r.M;case"q":case"quartile":return r.Q;case"h":case"high":return r.H;default:throw new Error("Unknown EC Level: "+n)}}r.isValid=function(t){return t&&typeof t.bit<"u"&&t.bit>=0&&t.bit<4},r.from=function(t,i){if(r.isValid(t))return t;try{return e(t)}catch{return i}}})(Re)),Re}var Pe,Ct;function hr(){if(Ct)return Pe;Ct=1;function r(){this.buffer=[],this.length=0}return r.prototype={get:function(e){const n=Math.floor(e/8);return(this.buffer[n]>>>7-e%8&1)===1},put:function(e,n){for(let t=0;t<n;t++)this.putBit((e>>>n-t-1&1)===1)},getLengthInBits:function(){return this.length},putBit:function(e){const n=Math.floor(this.length/8);this.buffer.length<=n&&this.buffer.push(0),e&&(this.buffer[n]|=128>>>this.length%8),this.length++}},Pe=r,Pe}var ke,bt;function pr(){if(bt)return ke;bt=1;function r(e){if(!e||e<1)throw new Error("BitMatrix size must be defined and greater than 0");this.size=e,this.data=new Uint8Array(e*e),this.reservedBit=new Uint8Array(e*e)}return r.prototype.set=function(e,n,t,i){const s=e*this.size+n;this.data[s]=t,i&&(this.reservedBit[s]=!0)},r.prototype.get=function(e,n){return this.data[e*this.size+n]},r.prototype.xor=function(e,n,t){this.data[e*this.size+n]^=t},r.prototype.isReserved=function(e,n){return this.reservedBit[e*this.size+n]},ke=r,ke}var Ee={},vt;function gr(){return vt||(vt=1,(function(r){const e=H().getSymbolSize;r.getRowColCoords=function(t){if(t===1)return[];const i=Math.floor(t/7)+2,s=e(t),o=s===145?26:Math.ceil((s-13)/(2*i-2))*2,a=[s-7];for(let c=1;c<i-1;c++)a[c]=a[c-1]-o;return a.push(6),a.reverse()},r.getPositions=function(t){const i=[],s=r.getRowColCoords(t),o=s.length;for(let a=0;a<o;a++)for(let c=0;c<o;c++)a===0&&c===0||a===0&&c===o-1||a===o-1&&c===0||i.push([s[a],s[c]]);return i}})(Ee)),Ee}var xe={},St;function mr(){if(St)return xe;St=1;const r=H().getSymbolSize,e=7;return xe.getPositions=function(t){const i=r(t);return[[0,0],[i-e,0],[0,i-e]]},xe}var Ie={},Tt;function yr(){return Tt||(Tt=1,(function(r){r.Patterns={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};const e={N1:3,N2:3,N3:40,N4:10};r.isValid=function(i){return i!=null&&i!==""&&!isNaN(i)&&i>=0&&i<=7},r.from=function(i){return r.isValid(i)?parseInt(i,10):void 0},r.getPenaltyN1=function(i){const s=i.size;let o=0,a=0,c=0,f=null,u=null;for(let l=0;l<s;l++){a=c=0,f=u=null;for(let d=0;d<s;d++){let h=i.get(l,d);h===f?a++:(a>=5&&(o+=e.N1+(a-5)),f=h,a=1),h=i.get(d,l),h===u?c++:(c>=5&&(o+=e.N1+(c-5)),u=h,c=1)}a>=5&&(o+=e.N1+(a-5)),c>=5&&(o+=e.N1+(c-5))}return o},r.getPenaltyN2=function(i){const s=i.size;let o=0;for(let a=0;a<s-1;a++)for(let c=0;c<s-1;c++){const f=i.get(a,c)+i.get(a,c+1)+i.get(a+1,c)+i.get(a+1,c+1);(f===4||f===0)&&o++}return o*e.N2},r.getPenaltyN3=function(i){const s=i.size;let o=0,a=0,c=0;for(let f=0;f<s;f++){a=c=0;for(let u=0;u<s;u++)a=a<<1&2047|i.get(f,u),u>=10&&(a===1488||a===93)&&o++,c=c<<1&2047|i.get(u,f),u>=10&&(c===1488||c===93)&&o++}return o*e.N3},r.getPenaltyN4=function(i){let s=0;const o=i.data.length;for(let c=0;c<o;c++)s+=i.data[c];return Math.abs(Math.ceil(s*100/o/5)-10)*e.N4};function n(t,i,s){switch(t){case r.Patterns.PATTERN000:return(i+s)%2===0;case r.Patterns.PATTERN001:return i%2===0;case r.Patterns.PATTERN010:return s%3===0;case r.Patterns.PATTERN011:return(i+s)%3===0;case r.Patterns.PATTERN100:return(Math.floor(i/2)+Math.floor(s/3))%2===0;case r.Patterns.PATTERN101:return i*s%2+i*s%3===0;case r.Patterns.PATTERN110:return(i*s%2+i*s%3)%2===0;case r.Patterns.PATTERN111:return(i*s%3+(i+s)%2)%2===0;default:throw new Error("bad maskPattern:"+t)}}r.applyMask=function(i,s){const o=s.size;for(let a=0;a<o;a++)for(let c=0;c<o;c++)s.isReserved(c,a)||s.xor(c,a,n(i,c,a))},r.getBestMask=function(i,s){const o=Object.keys(r.Patterns).length;let a=0,c=1/0;for(let f=0;f<o;f++){s(f),r.applyMask(f,i);const u=r.getPenaltyN1(i)+r.getPenaltyN2(i)+r.getPenaltyN3(i)+r.getPenaltyN4(i);r.applyMask(f,i),u<c&&(c=u,a=f)}return a}})(Ie)),Ie}var ie={},Rt;function Ln(){if(Rt)return ie;Rt=1;const r=rt(),e=[1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,4,1,2,4,4,2,4,4,4,2,4,6,5,2,4,6,6,2,5,8,8,4,5,8,8,4,5,8,11,4,8,10,11,4,9,12,16,4,9,16,16,6,10,12,18,6,10,17,16,6,11,16,19,6,13,18,21,7,14,21,25,8,16,20,25,8,17,23,25,9,17,23,34,9,18,25,30,10,20,27,32,12,21,29,35,12,23,34,37,12,25,34,40,13,26,35,42,14,28,38,45,15,29,40,48,16,31,43,51,17,33,45,54,18,35,48,57,19,37,51,60,19,38,53,63,20,40,56,66,21,43,59,70,22,45,62,74,24,47,65,77,25,49,68,81],n=[7,10,13,17,10,16,22,28,15,26,36,44,20,36,52,64,26,48,72,88,36,64,96,112,40,72,108,130,48,88,132,156,60,110,160,192,72,130,192,224,80,150,224,264,96,176,260,308,104,198,288,352,120,216,320,384,132,240,360,432,144,280,408,480,168,308,448,532,180,338,504,588,196,364,546,650,224,416,600,700,224,442,644,750,252,476,690,816,270,504,750,900,300,560,810,960,312,588,870,1050,336,644,952,1110,360,700,1020,1200,390,728,1050,1260,420,784,1140,1350,450,812,1200,1440,480,868,1290,1530,510,924,1350,1620,540,980,1440,1710,570,1036,1530,1800,570,1064,1590,1890,600,1120,1680,1980,630,1204,1770,2100,660,1260,1860,2220,720,1316,1950,2310,750,1372,2040,2430];return ie.getBlocksCount=function(i,s){switch(s){case r.L:return e[(i-1)*4+0];case r.M:return e[(i-1)*4+1];case r.Q:return e[(i-1)*4+2];case r.H:return e[(i-1)*4+3];default:return}},ie.getTotalCodewordsCount=function(i,s){switch(s){case r.L:return n[(i-1)*4+0];case r.M:return n[(i-1)*4+1];case r.Q:return n[(i-1)*4+2];case r.H:return n[(i-1)*4+3];default:return}},ie}var De={},ee={},Pt;function _r(){if(Pt)return ee;Pt=1;const r=new Uint8Array(512),e=new Uint8Array(256);return(function(){let t=1;for(let i=0;i<255;i++)r[i]=t,e[t]=i,t<<=1,t&256&&(t^=285);for(let i=255;i<512;i++)r[i]=r[i-255]})(),ee.log=function(t){if(t<1)throw new Error("log("+t+")");return e[t]},ee.exp=function(t){return r[t]},ee.mul=function(t,i){return t===0||i===0?0:r[e[t]+e[i]]},ee}var kt;function Cr(){return kt||(kt=1,(function(r){const e=_r();r.mul=function(t,i){const s=new Uint8Array(t.length+i.length-1);for(let o=0;o<t.length;o++)for(let a=0;a<i.length;a++)s[o+a]^=e.mul(t[o],i[a]);return s},r.mod=function(t,i){let s=new Uint8Array(t);for(;s.length-i.length>=0;){const o=s[0];for(let c=0;c<i.length;c++)s[c]^=e.mul(i[c],o);let a=0;for(;a<s.length&&s[a]===0;)a++;s=s.slice(a)}return s},r.generateECPolynomial=function(t){let i=new Uint8Array([1]);for(let s=0;s<t;s++)i=r.mul(i,new Uint8Array([1,e.exp(s)]));return i}})(De)),De}var Me,Et;function br(){if(Et)return Me;Et=1;const r=Cr();function e(n){this.genPoly=void 0,this.degree=n,this.degree&&this.initialize(this.degree)}return e.prototype.initialize=function(t){this.degree=t,this.genPoly=r.generateECPolynomial(this.degree)},e.prototype.encode=function(t){if(!this.genPoly)throw new Error("Encoder not initialized");const i=new Uint8Array(t.length+this.degree);i.set(t);const s=r.mod(i,this.genPoly),o=this.degree-s.length;if(o>0){const a=new Uint8Array(this.degree);return a.set(s,o),a}return s},Me=e,Me}var Ae={},Le={},Be={},xt;function Bn(){return xt||(xt=1,Be.isValid=function(e){return!isNaN(e)&&e>=1&&e<=40}),Be}var U={},It;function On(){if(It)return U;It=1;const r="[0-9]+",e="[A-Z $%*+\\-./:]+";let n="(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";n=n.replace(/u/g,"\\u");const t="(?:(?![A-Z0-9 $%*+\\-./:]|"+n+`)(?:.|[\r
|
|
42
42
|
]))+`;U.KANJI=new RegExp(n,"g"),U.BYTE_KANJI=new RegExp("[^A-Z0-9 $%*+\\-./:]+","g"),U.BYTE=new RegExp(t,"g"),U.NUMERIC=new RegExp(r,"g"),U.ALPHANUMERIC=new RegExp(e,"g");const i=new RegExp("^"+n+"$"),s=new RegExp("^"+r+"$"),o=new RegExp("^[A-Z0-9 $%*+\\-./:]+$");return U.testKanji=function(c){return i.test(c)},U.testNumeric=function(c){return s.test(c)},U.testAlphanumeric=function(c){return o.test(c)},U}var Dt;function K(){return Dt||(Dt=1,(function(r){const e=Bn(),n=On();r.NUMERIC={id:"Numeric",bit:1,ccBits:[10,12,14]},r.ALPHANUMERIC={id:"Alphanumeric",bit:2,ccBits:[9,11,13]},r.BYTE={id:"Byte",bit:4,ccBits:[8,16,16]},r.KANJI={id:"Kanji",bit:8,ccBits:[8,10,12]},r.MIXED={bit:-1},r.getCharCountIndicator=function(s,o){if(!s.ccBits)throw new Error("Invalid mode: "+s);if(!e.isValid(o))throw new Error("Invalid version: "+o);return o>=1&&o<10?s.ccBits[0]:o<27?s.ccBits[1]:s.ccBits[2]},r.getBestModeForData=function(s){return n.testNumeric(s)?r.NUMERIC:n.testAlphanumeric(s)?r.ALPHANUMERIC:n.testKanji(s)?r.KANJI:r.BYTE},r.toString=function(s){if(s&&s.id)return s.id;throw new Error("Invalid mode")},r.isValid=function(s){return s&&s.bit&&s.ccBits};function t(i){if(typeof i!="string")throw new Error("Param is not a string");switch(i.toLowerCase()){case"numeric":return r.NUMERIC;case"alphanumeric":return r.ALPHANUMERIC;case"kanji":return r.KANJI;case"byte":return r.BYTE;default:throw new Error("Unknown mode: "+i)}}r.from=function(s,o){if(r.isValid(s))return s;try{return t(s)}catch{return o}}})(Le)),Le}var Mt;function vr(){return Mt||(Mt=1,(function(r){const e=H(),n=Ln(),t=rt(),i=K(),s=Bn(),o=7973,a=e.getBCHDigit(o);function c(d,h,g){for(let _=1;_<=40;_++)if(h<=r.getCapacity(_,g,d))return _}function f(d,h){return i.getCharCountIndicator(d,h)+4}function u(d,h){let g=0;return d.forEach(function(_){const M=f(_.mode,h);g+=M+_.getBitsLength()}),g}function l(d,h){for(let g=1;g<=40;g++)if(u(d,g)<=r.getCapacity(g,h,i.MIXED))return g}r.from=function(h,g){return s.isValid(h)?parseInt(h,10):g},r.getCapacity=function(h,g,_){if(!s.isValid(h))throw new Error("Invalid QR Code version");typeof _>"u"&&(_=i.BYTE);const M=e.getSymbolTotalCodewords(h),k=n.getTotalCodewordsCount(h,g),I=(M-k)*8;if(_===i.MIXED)return I;const E=I-f(_,h);switch(_){case i.NUMERIC:return Math.floor(E/10*3);case i.ALPHANUMERIC:return Math.floor(E/11*2);case i.KANJI:return Math.floor(E/13);case i.BYTE:default:return Math.floor(E/8)}},r.getBestVersionForData=function(h,g){let _;const M=t.from(g,t.M);if(Array.isArray(h)){if(h.length>1)return l(h,M);if(h.length===0)return 1;_=h[0]}else _=h;return c(_.mode,_.getLength(),M)},r.getEncodedBits=function(h){if(!s.isValid(h)||h<7)throw new Error("Invalid QR Code version");let g=h<<12;for(;e.getBCHDigit(g)-a>=0;)g^=o<<e.getBCHDigit(g)-a;return h<<12|g}})(Ae)),Ae}var Oe={},At;function Sr(){if(At)return Oe;At=1;const r=H(),e=1335,n=21522,t=r.getBCHDigit(e);return Oe.getEncodedBits=function(s,o){const a=s.bit<<3|o;let c=a<<10;for(;r.getBCHDigit(c)-t>=0;)c^=e<<r.getBCHDigit(c)-t;return(a<<10|c)^n},Oe}var Ne={},Ue,Lt;function Tr(){if(Lt)return Ue;Lt=1;const r=K();function e(n){this.mode=r.NUMERIC,this.data=n.toString()}return e.getBitsLength=function(t){return 10*Math.floor(t/3)+(t%3?t%3*3+1:0)},e.prototype.getLength=function(){return this.data.length},e.prototype.getBitsLength=function(){return e.getBitsLength(this.data.length)},e.prototype.write=function(t){let i,s,o;for(i=0;i+3<=this.data.length;i+=3)s=this.data.substr(i,3),o=parseInt(s,10),t.put(o,10);const a=this.data.length-i;a>0&&(s=this.data.substr(i),o=parseInt(s,10),t.put(o,a*3+1))},Ue=e,Ue}var $e,Bt;function Rr(){if(Bt)return $e;Bt=1;const r=K(),e=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function n(t){this.mode=r.ALPHANUMERIC,this.data=t}return n.getBitsLength=function(i){return 11*Math.floor(i/2)+6*(i%2)},n.prototype.getLength=function(){return this.data.length},n.prototype.getBitsLength=function(){return n.getBitsLength(this.data.length)},n.prototype.write=function(i){let s;for(s=0;s+2<=this.data.length;s+=2){let o=e.indexOf(this.data[s])*45;o+=e.indexOf(this.data[s+1]),i.put(o,11)}this.data.length%2&&i.put(e.indexOf(this.data[s]),6)},$e=n,$e}var Fe,Ot;function Pr(){if(Ot)return Fe;Ot=1;const r=K();function e(n){this.mode=r.BYTE,typeof n=="string"?this.data=new TextEncoder().encode(n):this.data=new Uint8Array(n)}return e.getBitsLength=function(t){return t*8},e.prototype.getLength=function(){return this.data.length},e.prototype.getBitsLength=function(){return e.getBitsLength(this.data.length)},e.prototype.write=function(n){for(let t=0,i=this.data.length;t<i;t++)n.put(this.data[t],8)},Fe=e,Fe}var je,Nt;function kr(){if(Nt)return je;Nt=1;const r=K(),e=H();function n(t){this.mode=r.KANJI,this.data=t}return n.getBitsLength=function(i){return i*13},n.prototype.getLength=function(){return this.data.length},n.prototype.getBitsLength=function(){return n.getBitsLength(this.data.length)},n.prototype.write=function(t){let i;for(i=0;i<this.data.length;i++){let s=e.toSJIS(this.data[i]);if(s>=33088&&s<=40956)s-=33088;else if(s>=57408&&s<=60351)s-=49472;else throw new Error("Invalid SJIS character: "+this.data[i]+`
|
|
43
43
|
Make sure your charset is UTF-8`);s=(s>>>8&255)*192+(s&255),t.put(s,13)}},je=n,je}var ze={exports:{}},Ut;function Er(){return Ut||(Ut=1,(function(r){var e={single_source_shortest_paths:function(n,t,i){var s={},o={};o[t]=0;var a=e.PriorityQueue.make();a.push(t,0);for(var c,f,u,l,d,h,g,_,M;!a.empty();){c=a.pop(),f=c.value,l=c.cost,d=n[f]||{};for(u in d)d.hasOwnProperty(u)&&(h=d[u],g=l+h,_=o[u],M=typeof o[u]>"u",(M||_>g)&&(o[u]=g,a.push(u,g),s[u]=f))}if(typeof i<"u"&&typeof o[i]>"u"){var k=["Could not find a path from ",t," to ",i,"."].join("");throw new Error(k)}return s},extract_shortest_path_from_predecessor_list:function(n,t){for(var i=[],s=t;s;)i.push(s),n[s],s=n[s];return i.reverse(),i},find_path:function(n,t,i){var s=e.single_source_shortest_paths(n,t,i);return e.extract_shortest_path_from_predecessor_list(s,i)},PriorityQueue:{make:function(n){var t=e.PriorityQueue,i={},s;n=n||{};for(s in t)t.hasOwnProperty(s)&&(i[s]=t[s]);return i.queue=[],i.sorter=n.sorter||t.default_sorter,i},default_sorter:function(n,t){return n.cost-t.cost},push:function(n,t){var i={value:n,cost:t};this.queue.push(i),this.queue.sort(this.sorter)},pop:function(){return this.queue.shift()},empty:function(){return this.queue.length===0}}};r.exports=e})(ze)),ze.exports}var $t;function xr(){return $t||($t=1,(function(r){const e=K(),n=Tr(),t=Rr(),i=Pr(),s=kr(),o=On(),a=H(),c=Er();function f(k){return unescape(encodeURIComponent(k)).length}function u(k,I,E){const R=[];let A;for(;(A=k.exec(E))!==null;)R.push({data:A[0],index:A.index,mode:I,length:A[0].length});return R}function l(k){const I=u(o.NUMERIC,e.NUMERIC,k),E=u(o.ALPHANUMERIC,e.ALPHANUMERIC,k);let R,A;return a.isKanjiModeEnabled()?(R=u(o.BYTE,e.BYTE,k),A=u(o.KANJI,e.KANJI,k)):(R=u(o.BYTE_KANJI,e.BYTE,k),A=[]),I.concat(E,R,A).sort(function(S,v){return S.index-v.index}).map(function(S){return{data:S.data,mode:S.mode,length:S.length}})}function d(k,I){switch(I){case e.NUMERIC:return n.getBitsLength(k);case e.ALPHANUMERIC:return t.getBitsLength(k);case e.KANJI:return s.getBitsLength(k);case e.BYTE:return i.getBitsLength(k)}}function h(k){return k.reduce(function(I,E){const R=I.length-1>=0?I[I.length-1]:null;return R&&R.mode===E.mode?(I[I.length-1].data+=E.data,I):(I.push(E),I)},[])}function g(k){const I=[];for(let E=0;E<k.length;E++){const R=k[E];switch(R.mode){case e.NUMERIC:I.push([R,{data:R.data,mode:e.ALPHANUMERIC,length:R.length},{data:R.data,mode:e.BYTE,length:R.length}]);break;case e.ALPHANUMERIC:I.push([R,{data:R.data,mode:e.BYTE,length:R.length}]);break;case e.KANJI:I.push([R,{data:R.data,mode:e.BYTE,length:f(R.data)}]);break;case e.BYTE:I.push([{data:R.data,mode:e.BYTE,length:f(R.data)}])}}return I}function _(k,I){const E={},R={start:{}};let A=["start"];for(let y=0;y<k.length;y++){const S=k[y],v=[];for(let m=0;m<S.length;m++){const P=S[m],C=""+y+m;v.push(C),E[C]={node:P,lastCount:0},R[C]={};for(let T=0;T<A.length;T++){const b=A[T];E[b]&&E[b].node.mode===P.mode?(R[b][C]=d(E[b].lastCount+P.length,P.mode)-d(E[b].lastCount,P.mode),E[b].lastCount+=P.length):(E[b]&&(E[b].lastCount=P.length),R[b][C]=d(P.length,P.mode)+4+e.getCharCountIndicator(P.mode,I))}}A=v}for(let y=0;y<A.length;y++)R[A[y]].end=0;return{map:R,table:E}}function M(k,I){let E;const R=e.getBestModeForData(k);if(E=e.from(I,R),E!==e.BYTE&&E.bit<R.bit)throw new Error('"'+k+'" cannot be encoded with mode '+e.toString(E)+`.
|
|
44
44
|
Suggested mode is: `+e.toString(R));switch(E===e.KANJI&&!a.isKanjiModeEnabled()&&(E=e.BYTE),E){case e.NUMERIC:return new n(k);case e.ALPHANUMERIC:return new t(k);case e.KANJI:return new s(k);case e.BYTE:return new i(k)}}r.fromArray=function(I){return I.reduce(function(E,R){return typeof R=="string"?E.push(M(R,null)):R.data&&E.push(M(R.data,R.mode)),E},[])},r.fromString=function(I,E){const R=l(I,a.isKanjiModeEnabled()),A=g(R),y=_(A,E),S=c.find_path(y.map,"start","end"),v=[];for(let m=1;m<S.length-1;m++)v.push(y.table[S[m]].node);return r.fromArray(h(v))},r.rawSplit=function(I){return r.fromArray(l(I,a.isKanjiModeEnabled()))}})(Ne)),Ne}var Ft;function Ir(){if(Ft)return Te;Ft=1;const r=H(),e=rt(),n=hr(),t=pr(),i=gr(),s=mr(),o=yr(),a=Ln(),c=br(),f=vr(),u=Sr(),l=K(),d=xr();function h(y,S){const v=y.size,m=s.getPositions(S);for(let P=0;P<m.length;P++){const C=m[P][0],T=m[P][1];for(let b=-1;b<=7;b++)if(!(C+b<=-1||v<=C+b))for(let x=-1;x<=7;x++)T+x<=-1||v<=T+x||(b>=0&&b<=6&&(x===0||x===6)||x>=0&&x<=6&&(b===0||b===6)||b>=2&&b<=4&&x>=2&&x<=4?y.set(C+b,T+x,!0,!0):y.set(C+b,T+x,!1,!0))}}function g(y){const S=y.size;for(let v=8;v<S-8;v++){const m=v%2===0;y.set(v,6,m,!0),y.set(6,v,m,!0)}}function _(y,S){const v=i.getPositions(S);for(let m=0;m<v.length;m++){const P=v[m][0],C=v[m][1];for(let T=-2;T<=2;T++)for(let b=-2;b<=2;b++)T===-2||T===2||b===-2||b===2||T===0&&b===0?y.set(P+T,C+b,!0,!0):y.set(P+T,C+b,!1,!0)}}function M(y,S){const v=y.size,m=f.getEncodedBits(S);let P,C,T;for(let b=0;b<18;b++)P=Math.floor(b/3),C=b%3+v-8-3,T=(m>>b&1)===1,y.set(P,C,T,!0),y.set(C,P,T,!0)}function k(y,S,v){const m=y.size,P=u.getEncodedBits(S,v);let C,T;for(C=0;C<15;C++)T=(P>>C&1)===1,C<6?y.set(C,8,T,!0):C<8?y.set(C+1,8,T,!0):y.set(m-15+C,8,T,!0),C<8?y.set(8,m-C-1,T,!0):C<9?y.set(8,15-C-1+1,T,!0):y.set(8,15-C-1,T,!0);y.set(m-8,8,1,!0)}function I(y,S){const v=y.size;let m=-1,P=v-1,C=7,T=0;for(let b=v-1;b>0;b-=2)for(b===6&&b--;;){for(let x=0;x<2;x++)if(!y.isReserved(P,b-x)){let j=!1;T<S.length&&(j=(S[T]>>>C&1)===1),y.set(P,b-x,j),C--,C===-1&&(T++,C=7)}if(P+=m,P<0||v<=P){P-=m,m=-m;break}}}function E(y,S,v){const m=new n;v.forEach(function(x){m.put(x.mode.bit,4),m.put(x.getLength(),l.getCharCountIndicator(x.mode,y)),x.write(m)});const P=r.getSymbolTotalCodewords(y),C=a.getTotalCodewordsCount(y,S),T=(P-C)*8;for(m.getLengthInBits()+4<=T&&m.put(0,4);m.getLengthInBits()%8!==0;)m.putBit(0);const b=(T-m.getLengthInBits())/8;for(let x=0;x<b;x++)m.put(x%2?17:236,8);return R(m,y,S)}function R(y,S,v){const m=r.getSymbolTotalCodewords(S),P=a.getTotalCodewordsCount(S,v),C=m-P,T=a.getBlocksCount(S,v),b=m%T,x=T-b,j=Math.floor(m/T),X=Math.floor(C/T),Un=X+1,it=j-X,$n=new c(it);let ge=0;const re=new Array(T),st=new Array(T);let me=0;const Fn=new Uint8Array(y.buffer);for(let Y=0;Y<T;Y++){const _e=Y<x?X:Un;re[Y]=Fn.slice(ge,ge+_e),st[Y]=$n.encode(re[Y]),ge+=_e,me=Math.max(me,_e)}const ye=new Uint8Array(m);let ot=0,$,F;for($=0;$<me;$++)for(F=0;F<T;F++)$<re[F].length&&(ye[ot++]=re[F][$]);for($=0;$<it;$++)for(F=0;F<T;F++)ye[ot++]=st[F][$];return ye}function A(y,S,v,m){let P;if(Array.isArray(y))P=d.fromArray(y);else if(typeof y=="string"){let j=S;if(!j){const X=d.rawSplit(y);j=f.getBestVersionForData(X,v)}P=d.fromString(y,j||40)}else throw new Error("Invalid data");const C=f.getBestVersionForData(P,v);if(!C)throw new Error("The amount of data is too big to be stored in a QR Code");if(!S)S=C;else if(S<C)throw new Error(`
|
|
45
45
|
The chosen QR Code version cannot contain this amount of data.
|
|
46
46
|
Minimum version required to store current data is: `+C+`.
|
|
47
47
|
`);const T=E(S,v,P),b=r.getSymbolSize(S),x=new t(b);return h(x,S),g(x),_(x,S),k(x,v,0),S>=7&&M(x,S),I(x,T),isNaN(m)&&(m=o.getBestMask(x,k.bind(null,x,v))),o.applyMask(m,x),k(x,v,m),{modules:x,version:S,errorCorrectionLevel:v,maskPattern:m,segments:P}}return Te.create=function(S,v){if(typeof S>"u"||S==="")throw new Error("No input text");let m=e.M,P,C;return typeof v<"u"&&(m=e.from(v.errorCorrectionLevel,e.M),P=f.from(v.version),C=o.from(v.maskPattern),v.toSJISFunc&&r.setToSJISFunction(v.toSJISFunc)),A(S,P,m,C)},Te}var we={},Ve={},jt;function Nn(){return jt||(jt=1,(function(r){function e(n){if(typeof n=="number"&&(n=n.toString()),typeof n!="string")throw new Error("Color should be defined as hex string");let t=n.slice().replace("#","").split("");if(t.length<3||t.length===5||t.length>8)throw new Error("Invalid hex color: "+n);(t.length===3||t.length===4)&&(t=Array.prototype.concat.apply([],t.map(function(s){return[s,s]}))),t.length===6&&t.push("F","F");const i=parseInt(t.join(""),16);return{r:i>>24&255,g:i>>16&255,b:i>>8&255,a:i&255,hex:"#"+t.slice(0,6).join("")}}r.getOptions=function(t){t||(t={}),t.color||(t.color={});const i=typeof t.margin>"u"||t.margin===null||t.margin<0?4:t.margin,s=t.width&&t.width>=21?t.width:void 0,o=t.scale||4;return{width:s,scale:s?4:o,margin:i,color:{dark:e(t.color.dark||"#000000ff"),light:e(t.color.light||"#ffffffff")},type:t.type,rendererOpts:t.rendererOpts||{}}},r.getScale=function(t,i){return i.width&&i.width>=t+i.margin*2?i.width/(t+i.margin*2):i.scale},r.getImageWidth=function(t,i){const s=r.getScale(t,i);return Math.floor((t+i.margin*2)*s)},r.qrToImageData=function(t,i,s){const o=i.modules.size,a=i.modules.data,c=r.getScale(o,s),f=Math.floor((o+s.margin*2)*c),u=s.margin*c,l=[s.color.light,s.color.dark];for(let d=0;d<f;d++)for(let h=0;h<f;h++){let g=(d*f+h)*4,_=s.color.light;if(d>=u&&h>=u&&d<f-u&&h<f-u){const M=Math.floor((d-u)/c),k=Math.floor((h-u)/c);_=l[a[M*o+k]?1:0]}t[g++]=_.r,t[g++]=_.g,t[g++]=_.b,t[g]=_.a}}})(Ve)),Ve}var zt;function Dr(){return zt||(zt=1,(function(r){const e=Nn();function n(i,s,o){i.clearRect(0,0,s.width,s.height),s.style||(s.style={}),s.height=o,s.width=o,s.style.height=o+"px",s.style.width=o+"px"}function t(){try{return document.createElement("canvas")}catch{throw new Error("You need to specify a canvas element")}}r.render=function(s,o,a){let c=a,f=o;typeof c>"u"&&(!o||!o.getContext)&&(c=o,o=void 0),o||(f=t()),c=e.getOptions(c);const u=e.getImageWidth(s.modules.size,c),l=f.getContext("2d"),d=l.createImageData(u,u);return e.qrToImageData(d.data,s,c),n(l,f,u),l.putImageData(d,0,0),f},r.renderToDataURL=function(s,o,a){let c=a;typeof c>"u"&&(!o||!o.getContext)&&(c=o,o=void 0),c||(c={});const f=r.render(s,o,c),u=c.type||"image/png",l=c.rendererOpts||{};return f.toDataURL(u,l.quality)}})(we)),we}var qe={},wt;function Mr(){if(wt)return qe;wt=1;const r=Nn();function e(i,s){const o=i.a/255,a=s+'="'+i.hex+'"';return o<1?a+" "+s+'-opacity="'+o.toFixed(2).slice(1)+'"':a}function n(i,s,o){let a=i+s;return typeof o<"u"&&(a+=" "+o),a}function t(i,s,o){let a="",c=0,f=!1,u=0;for(let l=0;l<i.length;l++){const d=Math.floor(l%s),h=Math.floor(l/s);!d&&!f&&(f=!0),i[l]?(u++,l>0&&d>0&&i[l-1]||(a+=f?n("M",d+o,.5+h+o):n("m",c,0),c=0,f=!1),d+1<s&&i[l+1]||(a+=n("h",u),u=0)):c++}return a}return qe.render=function(s,o,a){const c=r.getOptions(o),f=s.modules.size,u=s.modules.data,l=f+c.margin*2,d=c.color.light.a?"<path "+e(c.color.light,"fill")+' d="M0 0h'+l+"v"+l+'H0z"/>':"",h="<path "+e(c.color.dark,"stroke")+' d="'+t(u,f,c.margin)+'"/>',g='viewBox="0 0 '+l+" "+l+'"',M='<svg xmlns="http://www.w3.org/2000/svg" '+(c.width?'width="'+c.width+'" height="'+c.width+'" ':"")+g+' shape-rendering="crispEdges">'+d+h+`</svg>
|
|
48
|
-
`;return typeof a=="function"&&a(null,M),M},qe}var Vt;function Ar(){if(Vt)return Q;Vt=1;const r=dr(),e=Ir(),n=Dr(),t=Mr();function i(s,o,a,c,f){const u=[].slice.call(arguments,1),l=u.length,d=typeof u[l-1]=="function";if(!d&&!r())throw new Error("Callback required as last argument");if(d){if(l<2)throw new Error("Too few arguments provided");l===2?(f=a,a=o,o=c=void 0):l===3&&(o.getContext&&typeof f>"u"?(f=c,c=void 0):(f=c,c=a,a=o,o=void 0))}else{if(l<1)throw new Error("Too few arguments provided");return l===1?(a=o,o=c=void 0):l===2&&!o.getContext&&(c=a,a=o,o=void 0),new Promise(function(h,g){try{const _=e.create(a,c);h(s(_,o,c))}catch(_){g(_)}})}try{const h=e.create(a,c);f(null,s(h,o,c))}catch(h){f(h)}}return Q.create=e.create,Q.toCanvas=i.bind(null,n.render),Q.toDataURL=i.bind(null,n.renderToDataURL),Q.toString=i.bind(null,function(s,o,a){return t.render(s,a)}),Q}var Lr=Ar();const Br=Rn(Lr);class Or{constructor(e,n,t){this._playerConnections=new Map,this._invitationAccepted=new Map,this._connectionToPlayerId=new Map,this._onPlayerEvent=null,this._onPlayerEvent=n,this._gamepadUiUrl=e,this._peer=t?new he(t):new he,this._peer.on("open",i=>{console.log(`Host PeerJS ID: ${i}`)}),this._peer.on("connection",i=>{i.on("open",()=>{console.log(`Connection open for PeerJS ID: ${i.peer}`)}),i.on("data",s=>{if(this._onPlayerEvent){let o;if(typeof s=="string")try{o=JSON.parse(s)}catch{console.warn("Invalid JSON from player",i.peer,s);return}else if(typeof s=="object"&&s!==null)o=s;else{console.warn("Unexpected data type from player",i.peer,s);return}let a;if("playerId"in o&&typeof o.playerId=="string"&&(a=o.playerId),a===void 0){console.warn("Malformed event from player",i.peer,o);return}o.playerId=a,"action"in o&&"timestamp"in o?(o.action==="JOIN"&&(this._playerConnections.set(o.playerId,i),this._invitationAccepted.set(o.playerId,!0),this._connectionToPlayerId.set(i,o.playerId),
|
|
48
|
+
`;return typeof a=="function"&&a(null,M),M},qe}var Vt;function Ar(){if(Vt)return Q;Vt=1;const r=dr(),e=Ir(),n=Dr(),t=Mr();function i(s,o,a,c,f){const u=[].slice.call(arguments,1),l=u.length,d=typeof u[l-1]=="function";if(!d&&!r())throw new Error("Callback required as last argument");if(d){if(l<2)throw new Error("Too few arguments provided");l===2?(f=a,a=o,o=c=void 0):l===3&&(o.getContext&&typeof f>"u"?(f=c,c=void 0):(f=c,c=a,a=o,o=void 0))}else{if(l<1)throw new Error("Too few arguments provided");return l===1?(a=o,o=c=void 0):l===2&&!o.getContext&&(c=a,a=o,o=void 0),new Promise(function(h,g){try{const _=e.create(a,c);h(s(_,o,c))}catch(_){g(_)}})}try{const h=e.create(a,c);f(null,s(h,o,c))}catch(h){f(h)}}return Q.create=e.create,Q.toCanvas=i.bind(null,n.render),Q.toDataURL=i.bind(null,n.renderToDataURL),Q.toString=i.bind(null,function(s,o,a){return t.render(s,a)}),Q}var Lr=Ar();const Br=Rn(Lr);class Or{constructor(e,n,t){this._playerConnections=new Map,this._invitationAccepted=new Map,this._connectionToPlayerId=new Map,this._playerNames=new Map,this._onPlayerEvent=null,this._onPlayerEvent=n,this._gamepadUiUrl=e,this._peer=t?new he(t):new he,this._peer.on("open",i=>{console.log(`Host PeerJS ID: ${i}`)}),this._peer.on("connection",i=>{i.on("open",()=>{console.log(`Connection open for PeerJS ID: ${i.peer}`)}),i.on("data",s=>{if(this._onPlayerEvent){let o;if(typeof s=="string")try{o=JSON.parse(s)}catch{console.warn("Invalid JSON from player",i.peer,s);return}else if(typeof s=="object"&&s!==null)o=s;else{console.warn("Unexpected data type from player",i.peer,s);return}let a;if("playerId"in o&&typeof o.playerId=="string"&&(a=o.playerId),a===void 0){console.warn("Malformed event from player",i.peer,o);return}o.playerId=a,"action"in o&&"timestamp"in o?(o.action==="JOIN"&&(this._playerConnections.set(o.playerId,i),this._invitationAccepted.set(o.playerId,!0),this._connectionToPlayerId.set(i,o.playerId),this._playerNames.set(o.playerId,o.playerName)),o.action==="MOVE"&&(o.playerName=this._playerNames.get(o.playerId)||""),this._onPlayerEvent(o)):console.warn("Malformed event from player",i.peer,o)}}),i.on("close",()=>{const s=this._connectionToPlayerId.get(i);if(s!==void 0){this._playerConnections.delete(s),this._invitationAccepted.delete(s),this._connectionToPlayerId.delete(i);const o=this._playerNames.get(s)||"";this._playerNames.delete(s),this._onPlayerEvent&&this._onPlayerEvent({playerId:s,action:"LEAVE",playerName:o,timestamp:Date.now()}),console.log(`Player ${s} disconnected`)}else console.log(`Connection closed for unknown player (PeerJS ID: ${i.peer})`)}),i.on("error",s=>{const o=this._connectionToPlayerId.get(i);o!==void 0?(console.error(`Connection error for player ${o}:`,s),this._playerConnections.delete(o),this._invitationAccepted.delete(o),this._connectionToPlayerId.delete(i),this._playerNames.delete(o)):console.error(`Connection error for unknown player (PeerJS ID: ${i.peer}):`,s)})}),this._peer.on("error",i=>{console.error("PeerJS error:",i)})}async createLobby(){return new Promise((e,n)=>{if(this._peer.destroyed||!this._peer.open)return n(new Error("Host Peer is not open or has been destroyed"));const t=this._peer.id;if(!t)return n(new Error("Host Peer ID not yet assigned"));const i=`${this._gamepadUiUrl}?hostPeerId=${encodeURIComponent(t)}`;Br.toDataURL(i,{errorCorrectionLevel:"M"},(s,o)=>{if(s)return n(s);e({dataUrl:o,shareURL:i})})})}getInvitationStatus(e){return this._invitationAccepted.get(e)}destroy(){for(const e of this._playerConnections.keys())this._invitationAccepted.delete(e);this._playerConnections.clear(),this._invitationAccepted.clear(),this._connectionToPlayerId.clear(),this._playerNames.clear(),this._peer.destroy()}}exports.Match=Or;exports.Player=lr;
|