-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
324 lines (300 loc) · 28.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<!DOCTYPE html>
<!-- Created with https://packager.turbowarp.org/ -->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- We only include this to explicitly loosen the CSP of various packager environments. It does not provide any security. -->
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: blob:">
<title></title>
<style>
body {
color: #ffffff;
font-family: sans-serif;
overflow: hidden;
margin: 0;
padding: 0;
}
:root, body.is-fullscreen {
background-color: #000000;
}
[hidden] {
display: none !important;
}
h1 {
font-weight: normal;
}
a {
color: inherit;
text-decoration: underline;
cursor: pointer;
}
#app, #loading, #error, #launch {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.screen {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
cursor: default;
user-select: none;
-webkit-user-select: none;
background-color: #000000;
}
#launch {
background-color: rgba(0, 0, 0, 0.7);
cursor: pointer;
}
.green-flag {
width: 80px;
height: 80px;
padding: 16px;
border-radius: 100%;
background: rgba(255, 255, 255, 0.75);
border: 3px solid hsla(0, 100%, 100%, 1);
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
#loading {
}
.progress-bar-outer {
border: 1px solid currentColor;
height: 10px;
width: 200px;
max-width: 200px;
}
.progress-bar-inner {
height: 100%;
width: 0;
background-color: currentColor;
}
.loading-text, noscript {
font-weight: normal;
font-size: 36px;
margin: 0 0 16px;
}
.loading-image {
margin: 0 0 16px;
}
#error-message, #error-stack {
font-family: monospace;
max-width: 600px;
white-space: pre-wrap;
user-select: text;
-webkit-user-select: text;
}
#error-stack {
text-align: left;
max-height: 200px;
overflow: auto;
}
.control-button {
width: 2rem;
height: 2rem;
padding: 0.375rem;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
user-select: none;
-webkit-user-select: none;
cursor: pointer;
border: 0;
border-radius: 4px;
}
.control-button:hover {
background: #ff4c4c26;
}
.control-button.active {
background: #ff4c4c59;
}
.fullscreen-button {
background: white !important;
}
.standalone-fullscreen-button {
position: absolute;
top: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 0 0 0 4px;
padding: 4px;
cursor: pointer;
}
.sc-canvas {
cursor: auto;
}
.sc-monitor-root[data-opcode^="data_"] .sc-monitor-value-color {
background-color: #ff8c1a;
}
.sc-monitor-row-value-outer {
background-color: #fc662c;
}
.sc-monitor-row-value-editing .sc-monitor-row-value-outer {
background-color: #e25b27;
}
</style>
<meta name="theme-color" content="#000000">
</head>
<body>
<div id="app"></div>
<div id="launch" class="screen" hidden title="Click to start">
<div class="green-flag">
<svg viewBox="0 0 16.63 17.5" width="42" height="44">
<defs><style>.cls-1,.cls-2{fill:#4cbf56;stroke:#45993d;stroke-linecap:round;stroke-linejoin:round;}.cls-2{stroke-width:1.5px;}</style></defs>
<path class="cls-1" d="M.75,2A6.44,6.44,0,0,1,8.44,2h0a6.44,6.44,0,0,0,7.69,0V12.4a6.44,6.44,0,0,1-7.69,0h0a6.44,6.44,0,0,0-7.69,0"/>
<line class="cls-2" x1="0.75" y1="16.75" x2="0.75" y2="0.75"/>
</svg>
</div>
</div>
<div id="loading" class="screen">
<noscript>Enable JavaScript</noscript>
</div>
<div id="error" class="screen" hidden>
<h1>Error</h1>
<details>
<summary id="error-message"></summary>
<p id="error-stack"></p>
</details>
</div>
<script src="script.js"></script>
<script>
const appElement = document.getElementById('app');
const launchScreen = document.getElementById('launch');
const loadingScreen = document.getElementById('loading');
const loadingInner = document.getElementById('loading-inner');
const errorScreen = document.getElementById('error');
const errorScreenMessage = document.getElementById('error-message');
const errorScreenStack = document.getElementById('error-stack');
const handleError = (error) => {
console.error(error);
if (!errorScreen.hidden) return;
errorScreen.hidden = false;
errorScreenMessage.textContent = '' + error;
let debug = error && error.stack || 'no stack';
debug += '\nUser agent: ' + navigator.userAgent;
errorScreenStack.textContent = debug;
};
const setProgress = (progress) => {
if (loadingInner) loadingInner.style.width = progress * 100 + '%';
};
const interpolate = (a, b, t) => a + t * (b - a);
try {
setProgress(0.1);
const scaffolding = new Scaffolding.Scaffolding();
scaffolding.width = 480;
scaffolding.height = 360;
scaffolding.resizeMode = "preserve-ratio";
scaffolding.editableLists = false;
scaffolding.usePackagedRuntime = true;
scaffolding.setup();
scaffolding.appendTo(appElement);
const vm = scaffolding.vm;
window.scaffolding = scaffolding;
window.vm = scaffolding.vm;
window.Scratch = {
vm,
renderer: vm.renderer,
audioEngine: vm.runtime.audioEngine,
bitmapAdapter: vm.runtime.v2BitmapAdapter,
videoProvider: vm.runtime.ioDevices.video.provider
};
scaffolding.setUsername("player####".replace(/#/g, () => Math.floor(Math.random() * 10)));
scaffolding.setAccentColor("#ff4c4c");
try {
scaffolding.addCloudProvider(new Scaffolding.Cloud.WebSocketProvider(["wss://clouddata.turbowarp.org","wss://clouddata.turbowarp.xyz"], "o"));
} catch (error) {
console.error(error);
}
vm.setTurboMode(true);
if (vm.setInterpolation) vm.setInterpolation(false);
if (vm.setFramerate) vm.setFramerate(240);
if (vm.renderer.setUseHighQualityRender) vm.renderer.setUseHighQualityRender(false);
if (vm.setRuntimeOptions) vm.setRuntimeOptions({
fencing: false,
miscLimits: false,
maxClones: 9999999999,
});
if (vm.setCompilerOptions) vm.setCompilerOptions({
enabled: true,
warpTimer: false
});
if (vm.renderer.setMaxTextureDimension) vm.renderer.setMaxTextureDimension(2048);
if (typeof ScaffoldingAddons !== 'undefined') {
ScaffoldingAddons.run(scaffolding, {"gamepad":false,"pointerlock":false,"specialCloudBehaviors":false,"unsafeCloudBehaviors":false,"pause":false});
}
scaffolding.setExtensionSecurityManager({
getSandboxMode: () => 'unsandboxed',
canLoadExtensionFromProject: () => true
});
for (const extension of ["data:text/javascript;,(function(Scratch)%20%7B%20%2F%2F%20Name%3A%20Browser%20Fullscreen%0D%0A%2F%2F%20ID%3A%20fullscreen0419%0D%0A%2F%2F%20Description%3A%20Enter%20and%20exit%20fullscreen%20mode.%0D%0A%2F%2F%20By%3A%20Veggiecan0419%0D%0A%2F%2F%20License%3A%20MIT%0D%0A%0D%0A(function%20(Scratch)%20%7B%0D%0A%20%20%22use%20strict%22%3B%0D%0A%20%20const%20icon%20%3D%0D%0A%20%20%20%20%22data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI2My4yNjc0MiIgaGVpZ2h0PSI2My4xODQ5NSIgdmlld0JveD0iMCwwLDYzLjI2NzQyLDYzLjE4NDk1Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjA4LjM2NjI5LC0xNDguNDA3NTMpIj48ZyBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpc1BhaW50aW5nTGF5ZXImcXVvdDs6dHJ1ZX0iIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWRhc2hhcnJheT0iIiBzdHJva2UtZGFzaG9mZnNldD0iMCIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9IiIgZmlsbD0iI2ZmZDI0ZCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9IiIgZmlsbD0iIzAxMDEwMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9IiIgZmlsbD0iIzAxMDEwMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9IiIgZmlsbD0iIzAxMDEwMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9IiIgZmlsbD0iIzAxMDEwMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9IiIgZmlsbD0iIzAwMDAwMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9IiIgZmlsbD0iIzAwMDAwMCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAuNSIvPjxwYXRoIGQ9Ik0yNjkuNjMzNzEsMTgwYzAsMTYuMzQzNDcgLTEzLjI2NzQ3LDI5LjU5MjQ4IC0yOS42MzM3MSwyOS41OTI0OGMtMTYuMzY2MjUsMCAtMjkuNjMzNzEsLTEzLjI0OTAxIC0yOS42MzM3MSwtMjkuNTkyNDhjMCwtMTYuMzQzNDcgMTMuMjY3NDcsLTI5LjU5MjQ3IDI5LjYzMzcxLC0yOS41OTI0N2MxNi4zNjYyNSwwIDI5LjYzMzcxLDEzLjI0OSAyOS42MzM3MSwyOS41OTI0N3oiIGZpbGw9IiNmZmQyNGQiIHN0cm9rZT0iI2ZmZDI0ZCIgc3Ryb2tlLXdpZHRoPSI0Ii8%2BPGcgc3Ryb2tlLXdpZHRoPSI1Ij48ZyBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAwMDAiPjxwYXRoIGQ9Ik0yNjAuMjA3MDEsMTY3LjcwODg3YzAsMCAtMy43NDA3NSwtMS45MjU0NCAtNS4xOTI2MywtMi42NzI3NmMtMS4wNDg4LC0wLjUzOTg0IC0xLjQ3OTgyLC0wLjk5NjMxIC0xLjQ3OTgyLC0wLjk5NjMxbDYuNjgyMzksLTAuMjE1Njl6Ii8%2BPGc%2BPHBhdGggZD0iTTIyNy45OTM3NiwxOTYuMDEwNDFsMjQuMTE4NywtMzAuNTQ3OTdsMi4xODE5OSwxLjcyMjc2bC0yNC4xMTg3LDMwLjU0Nzk3eiIvPjxwYXRoIGQ9Ik0yNTguMTI3ODQsMTkyLjk2MTIybC0zNS4yMjk0OSwtMjUuMjk0NjZsMC45NzI4OCwtMS4zNTQ5OWwzNS4yMjk0OSwyNS4yOTQ2NnoiLz48cGF0aCBkPSJNMjI1LjM4ODcsMTYyLjM1NzIxYzAsMCAtMi42NzQ1NCwzLjQzOTM1IC0zLjcxMjYsNC43NzQyNWMtMC43NDk4NywwLjk2NDMgLTEuMjg3MzQsMS4zMDg5MSAtMS4yODczNCwxLjMwODkxbDEuMjA1MjksLTYuOTQ4OTZ6Ii8%2BPHBhdGggZD0iTTI1Ni4wOTcxMiwxOTUuNDE3NDFjMCwwIDMuMTk3ODMsLTIuOTU5MDkgNC40Mzg5OSwtNC4xMDc1OWMwLjg5NjU5LC0wLjgyOTY1IDEuNDgyOSwtMS4wODIzNSAxLjQ4MjksLTEuMDgyMzVsLTIuMzE4MzQsNi42NjA3OXoiLz48cGF0aCBkPSJNMjI1LjAzMDcxLDE5NS40MTMwN2MwLDAgMy42NDk1NiwyLjM3OTcxIDUuMDY2MDQsMy4zMDMzNGMxLjAyMzI0LDAuNjY3MjEgMS40MTEyOSwxLjE3NDIgMS40MTEyOSwxLjE3NDJsLTcuMDI1MDUsLTAuNjI0MXoiLz48L2c%2BPC9nPjxwYXRoIGQ9Ik0yMzIuOTYyNDgsMTgxLjk4NjUxbDcuMTQ2NjYsLTEwLjgyODAzbDEwLjY3MzM2LDcuMDQ0NTdsLTcuMTQ2NjYsMTAuODI4MDN6IiBmaWxsPSIjZmZkMjRkIiBzdHJva2U9Im5vbmUiLz48L2c%2BPC9nPjwvZz48L3N2Zz4%3D%22%3B%0D%0A%0D%0A%20%20window.addEventListener(%22fullscreenchange%22%2C%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20Scratch.vm.runtime.startHats(%22fullscreen0419_whenfullscreen%22%2C%20%7B%0D%0A%20%20%20%20%20%20ENABLED%3A%20document.fullscreenElement%20%3D%3D%3D%20null%20%3F%20%22exited%22%20%3A%20%22entered%22%2C%0D%0A%20%20%20%20%7D)%3B%0D%0A%20%20%7D)%3B%0D%0A%0D%0A%20%20class%20FullscreenExtension%20%7B%0D%0A%20%20%20%20getInfo()%20%7B%0D%0A%20%20%20%20%20%20return%20%7B%0D%0A%20%20%20%20%20%20%20%20id%3A%20%22fullscreen0419%22%2C%0D%0A%20%20%20%20%20%20%20%20color1%3A%20%22%23F39016%22%2C%0D%0A%20%20%20%20%20%20%20%20color2%3A%20%22%23C77612%22%2C%0D%0A%20%20%20%20%20%20%20%20color3%3A%20%22%239D5D0E%22%2C%0D%0A%20%20%20%20%20%20%20%20blockIconURI%3A%20icon%2C%0D%0A%20%20%20%20%20%20%20%20name%3A%20%22Browser%20Fullscreen%22%2C%0D%0A%20%20%20%20%20%20%20%20blocks%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20%22fullscreen%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.COMMAND%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22%5BACTION%5D%20fullscreen%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20arguments%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20ACTION%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20Scratch.ArgumentType.STRING%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu%3A%20%22fullscreenMenu%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20defaultValue%3A%20%22enter%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20%22isInFullscreen%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.BOOLEAN%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22in%20browser%20fullscreen%3F%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20arguments%3A%20%7B%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20%22whenfullscreen%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.EVENT%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22when%20browser%20fullscreen%20%5BENABLED%5D%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20isEdgeActivated%3A%20false%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20arguments%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20ENABLED%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20Scratch.ArgumentType.STRING%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu%3A%20%22whenfullscreenMenu%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20menus%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20fullscreenMenu%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptReporters%3A%20true%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20items%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22enter%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3A%20%22enter%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22exit%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3A%20%22exit%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20whenfullscreenMenu%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Used%20for%20startHats%20filtering.%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptReporters%3A%20false%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20items%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22entered%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3A%20%22entered%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22exited%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3A%20%22exited%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%7D%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20fullscreen(args)%20%7B%0D%0A%20%20%20%20%20%20const%20action%20%3D%20args.ACTION%3B%0D%0A%20%20%20%20%20%20if%20(action%20%3D%3D%3D%20%22enter%22)%20%7B%0D%0A%20%20%20%20%20%20%20%20document.documentElement.requestFullscreen()%3B%0D%0A%20%20%20%20%20%20%7D%20else%20if%20(action%20%3D%3D%3D%20%22exit%22)%20%7B%0D%0A%20%20%20%20%20%20%20%20document.exitFullscreen()%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20isInFullscreen()%20%7B%0D%0A%20%20%20%20%20%20return%20document.fullscreenElement%20!%3D%3D%20null%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%0D%0A%0D%0A%20%20Scratch.extensions.register(new%20FullscreenExtension())%3B%0D%0A%7D)(Scratch)%3B%0D%0A%20%7D)(Scratch)%3B","data:text/javascript;,(function(Scratch)%20%7B%20%2F%2F%20Name%3A%20Pointerlock%0D%0A%2F%2F%20ID%3A%20pointerlock%0D%0A%2F%2F%20Description%3A%20Adds%20blocks%20for%20mouse%20locking.%20Mouse%20x%20%26%20y%20blocks%20will%20report%20the%20change%20since%20the%20previous%20frame%20while%20the%20pointer%20is%20locked.%20Replaces%20the%20pointerlock%20experiment.%0D%0A%2F%2F%20License%3A%20MIT%20AND%20MPL-2.0%0D%0A%0D%0A%2F*%20generated%20l10n%20code%20*%2FScratch.translate.setup(%7B%22de%22%3A%7B%22_Pointerlock%22%3A%22Zeigersperren%22%7D%2C%22fi%22%3A%7B%22_Pointerlock%22%3A%22Hiiren%20osoittimen%20lukitus%22%7D%2C%22it%22%3A%7B%22_Pointerlock%22%3A%22Blocco%20Puntatore%22%2C%22_disabled%22%3A%22sblocca%22%2C%22_enabled%22%3A%22blocca%22%2C%22_pointer%20locked%3F%22%3A%22puntatore%20bloccato%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22%5Benabled%5D%20puntatore%22%7D%2C%22ja%22%3A%7B%22_Pointerlock%22%3A%22%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%AD%E3%83%83%E3%82%AF%22%2C%22_disabled%22%3A%22%E7%84%A1%E5%8A%B9%22%2C%22_enabled%22%3A%22%E6%9C%89%E5%8A%B9%22%2C%22_pointer%20locked%3F%22%3A%22%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%81%AF%E3%83%AD%E3%83%83%E3%82%AF%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%AD%E3%83%83%E3%82%AF%E3%82%92%5Benabled%5D%E3%81%AB%E3%81%99%E3%82%8B%22%7D%2C%22nb%22%3A%7B%22_Pointerlock%22%3A%22Pointerl%C3%A5s%22%2C%22_disabled%22%3A%22deaktivert%22%2C%22_enabled%22%3A%22aktivert%22%2C%22_pointer%20locked%3F%22%3A%22peker%20l%C3%A5st%3F%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22sette%20pekerl%C3%A5s%20%5Benabled%5D%22%7D%2C%22nl%22%3A%7B%22_Pointerlock%22%3A%22Muisaanwijzer-vergrendeling%22%2C%22_disabled%22%3A%22ontgrendel%22%2C%22_enabled%22%3A%22vergrendel%22%2C%22_pointer%20locked%3F%22%3A%22muisaanwijzer%20vergrendeld%3F%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22%5Benabled%5D%20muisaanwijzer%22%7D%2C%22ru%22%3A%7B%22_disabled%22%3A%22%D0%B2%D1%8B%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%22%2C%22_enabled%22%3A%22%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%22%2C%22_pointer%20locked%3F%22%3A%22%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D1%8C%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%3F%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C%20%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D1%91%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0%20%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D0%B5%D0%BB%D1%8F%20%5Benabled%5D%22%7D%2C%22uk%22%3A%7B%22_disabled%22%3A%22%D1%80%D0%BE%D0%B7%D0%B1%D0%BB%D0%BE%D0%BA%D1%83%D0%B2%D0%B0%D1%82%D0%B8%22%2C%22_enabled%22%3A%22%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D1%83%D0%B2%D0%B0%D1%82%D0%B8%22%2C%22_pointer%20locked%3F%22%3A%22%D0%B2%D0%BA%D0%B0%D0%B7%D1%96%D0%B2%D0%BD%D0%B8%D0%BA%20%D0%B7%D0%B0%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2%D0%B0%D0%BD%D0%BE%3F%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22%5Benabled%5D%20%D0%B2%D0%BA%D0%B0%D0%B7%D1%96%D0%B2%D0%BD%D0%B8%D0%BA%20%D0%BC%D0%B8%D1%88%D1%96%22%7D%2C%22zh-cn%22%3A%7B%22_Pointerlock%22%3A%22%E9%BC%A0%E6%A0%87%E9%94%81%E5%AE%9A%22%2C%22_disabled%22%3A%22%E7%A6%81%E7%94%A8%22%2C%22_enabled%22%3A%22%E5%90%AF%E7%94%A8%22%2C%22_pointer%20locked%3F%22%3A%22%E6%8C%87%E9%92%88%E9%94%81%E5%AE%9A%EF%BC%9F%22%2C%22_set%20pointer%20lock%20%5Benabled%5D%22%3A%22%E8%AE%BE%E7%BD%AE%E6%8C%87%E9%92%88%E9%94%81%E5%AE%9A%E4%B8%BA%5Benabled%5D%22%7D%7D)%3B%2F*%20end%20generated%20l10n%20code%20*%2F(function%20(Scratch)%20%7B%0D%0A%20%20%22use%20strict%22%3B%0D%0A%0D%0A%20%20if%20(!Scratch.extensions.unsandboxed)%20%7B%0D%0A%20%20%20%20throw%20new%20Error(%22pointerlock%20extension%20must%20be%20run%20unsandboxed%22)%3B%0D%0A%20%20%7D%0D%0A%0D%0A%20%20const%20vm%20%3D%20Scratch.vm%3B%0D%0A%0D%0A%20%20const%20canvas%20%3D%20vm.runtime.renderer.canvas%3B%0D%0A%20%20const%20mouse%20%3D%20vm.runtime.ioDevices.mouse%3B%0D%0A%20%20let%20isLocked%20%3D%20false%3B%0D%0A%20%20let%20isPointerLockEnabled%20%3D%20false%3B%0D%0A%0D%0A%20%20let%20rect%20%3D%20canvas.getBoundingClientRect()%3B%0D%0A%20%20window.addEventListener(%22resize%22%2C%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20rect%20%3D%20canvas.getBoundingClientRect()%3B%0D%0A%20%20%7D)%3B%0D%0A%0D%0A%20%20const%20postMouseData%20%3D%20(e%2C%20isDown)%20%3D%3E%20%7B%0D%0A%20%20%20%20const%20%7B%20movementX%2C%20movementY%20%7D%20%3D%20e%3B%0D%0A%20%20%20%20const%20%7B%20width%2C%20height%20%7D%20%3D%20rect%3B%0D%0A%20%20%20%20const%20x%20%3D%20mouse._clientX%20%2B%20movementX%3B%0D%0A%20%20%20%20const%20y%20%3D%20mouse._clientY%20-%20movementY%3B%0D%0A%20%20%20%20mouse._clientX%20%3D%20x%3B%0D%0A%20%20%20%20mouse._scratchX%20%3D%20mouse.runtime.stageWidth%20*%20(x%20%2F%20width%20-%200.5)%3B%0D%0A%20%20%20%20mouse._clientY%20%3D%20y%3B%0D%0A%20%20%20%20mouse._scratchY%20%3D%20mouse.runtime.stageWidth%20*%20(y%20%2F%20height%20-%200.5)%3B%0D%0A%20%20%20%20if%20(typeof%20isDown%20%3D%3D%3D%20%22boolean%22)%20%7B%0D%0A%20%20%20%20%20%20const%20data%20%3D%20%7B%0D%0A%20%20%20%20%20%20%20%20button%3A%20e.button%2C%0D%0A%20%20%20%20%20%20%20%20isDown%2C%0D%0A%20%20%20%20%20%20%7D%3B%0D%0A%20%20%20%20%20%20originalPostIOData(data)%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20const%20mouseDevice%20%3D%20vm.runtime.ioDevices.mouse%3B%0D%0A%20%20const%20originalPostIOData%20%3D%20mouseDevice.postData.bind(mouseDevice)%3B%0D%0A%20%20mouseDevice.postData%20%3D%20(data)%20%3D%3E%20%7B%0D%0A%20%20%20%20if%20(!isPointerLockEnabled)%20%7B%0D%0A%20%20%20%20%20%20return%20originalPostIOData(data)%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20document.addEventListener(%0D%0A%20%20%20%20%22mousedown%22%2C%0D%0A%20%20%20%20(e)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20%2F%2F%20%40ts-expect-error%0D%0A%20%20%20%20%20%20if%20(canvas.contains(e.target))%20%7B%0D%0A%20%20%20%20%20%20%20%20if%20(isLocked)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20postMouseData(e%2C%20true)%3B%0D%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(isPointerLockEnabled)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20canvas.requestPointerLock()%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%2C%0D%0A%20%20%20%20true%0D%0A%20%20)%3B%0D%0A%20%20document.addEventListener(%0D%0A%20%20%20%20%22mouseup%22%2C%0D%0A%20%20%20%20(e)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20if%20(isLocked)%20%7B%0D%0A%20%20%20%20%20%20%20%20postMouseData(e%2C%20false)%3B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20%40ts-expect-error%0D%0A%20%20%20%20%20%20%7D%20else%20if%20(isPointerLockEnabled%20%26%26%20canvas.contains(e.target))%20%7B%0D%0A%20%20%20%20%20%20%20%20canvas.requestPointerLock()%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%2C%0D%0A%20%20%20%20true%0D%0A%20%20)%3B%0D%0A%20%20document.addEventListener(%0D%0A%20%20%20%20%22mousemove%22%2C%0D%0A%20%20%20%20(e)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20if%20(isLocked)%20%7B%0D%0A%20%20%20%20%20%20%20%20postMouseData(e)%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%2C%0D%0A%20%20%20%20true%0D%0A%20%20)%3B%0D%0A%0D%0A%20%20document.addEventListener(%22pointerlockchange%22%2C%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20isLocked%20%3D%20document.pointerLockElement%20%3D%3D%3D%20canvas%3B%0D%0A%20%20%7D)%3B%0D%0A%20%20document.addEventListener(%22pointerlockerror%22%2C%20(e)%20%3D%3E%20%7B%0D%0A%20%20%20%20console.error(%22Pointer%20lock%20error%22%2C%20e)%3B%0D%0A%20%20%7D)%3B%0D%0A%0D%0A%20%20const%20oldStep%20%3D%20vm.runtime._step%3B%0D%0A%20%20vm.runtime._step%20%3D%20function%20(...args)%20%7B%0D%0A%20%20%20%20const%20ret%20%3D%20oldStep.call(this%2C%20...args)%3B%0D%0A%20%20%20%20if%20(isPointerLockEnabled)%20%7B%0D%0A%20%20%20%20%20%20const%20%7B%20width%2C%20height%20%7D%20%3D%20rect%3B%0D%0A%20%20%20%20%20%20mouse._clientX%20%3D%20width%20%2F%202%3B%0D%0A%20%20%20%20%20%20mouse._clientY%20%3D%20height%20%2F%202%3B%0D%0A%20%20%20%20%20%20mouse._scratchX%20%3D%200%3B%0D%0A%20%20%20%20%20%20mouse._scratchY%20%3D%200%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20return%20ret%3B%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20vm.runtime.on(%22PROJECT_LOADED%22%2C%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20isPointerLockEnabled%20%3D%20false%3B%0D%0A%20%20%20%20if%20(isLocked)%20%7B%0D%0A%20%20%20%20%20%20document.exitPointerLock()%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D)%3B%0D%0A%0D%0A%20%20class%20Pointerlock%20%7B%0D%0A%20%20%20%20getInfo()%20%7B%0D%0A%20%20%20%20%20%20return%20%7B%0D%0A%20%20%20%20%20%20%20%20id%3A%20%22pointerlock%22%2C%0D%0A%20%20%20%20%20%20%20%20name%3A%20Scratch.translate(%22Pointerlock%22)%2C%0D%0A%20%20%20%20%20%20%20%20blocks%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20%22setLocked%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.COMMAND%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20Scratch.translate(%22set%20pointer%20lock%20%5Benabled%5D%22)%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20arguments%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20enabled%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20Scratch.ArgumentType.STRING%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20defaultValue%3A%20%22true%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu%3A%20%22enabled%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20%22isLocked%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.BOOLEAN%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20Scratch.translate(%22pointer%20locked%3F%22)%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20menus%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20enabled%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptReporters%3A%20true%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20items%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20Scratch.translate(%22enabled%22)%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3A%20%22true%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20Scratch.translate(%22disabled%22)%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%3A%20%22false%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%7D%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20setLocked(args)%20%7B%0D%0A%20%20%20%20%20%20isPointerLockEnabled%20%3D%20Scratch.Cast.toBoolean(args.enabled)%20%3D%3D%3D%20true%3B%0D%0A%20%20%20%20%20%20if%20(!isPointerLockEnabled%20%26%26%20isLocked)%20%7B%0D%0A%20%20%20%20%20%20%20%20document.exitPointerLock()%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20isLocked()%20%7B%0D%0A%20%20%20%20%20%20return%20isLocked%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%0D%0A%0D%0A%20%20Scratch.extensions.register(new%20Pointerlock())%3B%0D%0A%7D)(Scratch)%3B%0D%0A%20%7D)(Scratch)%3B"]) {
vm.extensionManager.loadExtensionURL(extension);
}
} catch (e) {
handleError(e);
}
</script>
<script>
const getProjectData = (function() {
const storage = scaffolding.storage;
storage.onprogress = (total, loaded) => {
setProgress(interpolate(0.2, 0.98, loaded / total));
};
storage.addWebStore(
[
storage.AssetType.ImageVector,
storage.AssetType.ImageBitmap,
storage.AssetType.Sound,
storage.AssetType.Font
].filter(i => i),
(asset) => new URL('./assets/' + asset.assetId + '.' + asset.dataFormat, location).href
);
return () => new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
resolve(xhr.response);
};
xhr.onerror = () => {
if (location.protocol === 'file:') {
reject(new Error('Zip environment must be used from a website, not from a file URL.'));
} else {
reject(new Error('Request to load project data failed.'));
}
};
xhr.onprogress = (e) => {
if (e.lengthComputable) {
setProgress(interpolate(0.1, 0.2, e.loaded / e.total));
}
};
xhr.responseType = 'arraybuffer';
xhr.open('GET', "./assets/project.json");
xhr.send();
});
})();
</script>
<script>
const run = async () => {
const projectData = await getProjectData();
await scaffolding.loadProject(projectData);
setProgress(1);
loadingScreen.hidden = true;
if (true) {
scaffolding.start();
} else {
launchScreen.hidden = false;
launchScreen.addEventListener('click', () => {
launchScreen.hidden = true;
scaffolding.start();
});
launchScreen.focus();
}
};
run().catch(handleError);
</script>
</body>
</html>