mlv2boii 1.0.5 → 1.0.6
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/holdw.py +21 -0
- package/index.html +107 -81
- package/loader.svg +26 -40
- package/package.json +1 -1
package/holdw.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import keyboard
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def start():
|
|
7
|
+
keyboard_pressing = True
|
|
8
|
+
while keyboard_pressing:
|
|
9
|
+
keyboard.press("W")
|
|
10
|
+
time.sleep(0.1)
|
|
11
|
+
|
|
12
|
+
if keyboard.is_pressed("C"):
|
|
13
|
+
keyboard_pressing = False
|
|
14
|
+
while not (keyboard.is_pressed("X")):
|
|
15
|
+
time.sleep(0.1)
|
|
16
|
+
keyboard_pressing = True; start()
|
|
17
|
+
|
|
18
|
+
start()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
package/index.html
CHANGED
|
@@ -70,22 +70,41 @@
|
|
|
70
70
|
@keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
|
|
71
71
|
.skel { background: linear-gradient(100deg, #18181c 30%, #202024 45%, #18181c 60%); background-size: 200% 100%; animation: shimmer 1.6s ease-in-out infinite; }
|
|
72
72
|
|
|
73
|
-
[data-fx] { will-change: transform, opacity; }
|
|
74
|
-
|
|
75
|
-
.hero-orb { animation: heroFloat 7s ease-in-out infinite; }
|
|
76
|
-
.hero-line { animation: heroLine 2.8s ease-in-out infinite; }
|
|
77
|
-
@keyframes heroFloat {
|
|
78
|
-
0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
|
|
79
|
-
50% { transform: translate3d(0, 12px, 0) scale(1.04); }
|
|
80
|
-
}
|
|
81
|
-
@keyframes heroLine {
|
|
82
|
-
0%, 100% { opacity: .35; transform: scaleX(.7); }
|
|
83
|
-
50% { opacity: 1; transform: scaleX(1); }
|
|
84
|
-
}
|
|
85
|
-
|
|
73
|
+
[data-fx] { will-change: transform, opacity; }
|
|
74
|
+
|
|
75
|
+
.hero-orb { animation: heroFloat 7s ease-in-out infinite; }
|
|
76
|
+
.hero-line { animation: heroLine 2.8s ease-in-out infinite; }
|
|
77
|
+
@keyframes heroFloat {
|
|
78
|
+
0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
|
|
79
|
+
50% { transform: translate3d(0, 12px, 0) scale(1.04); }
|
|
80
|
+
}
|
|
81
|
+
@keyframes heroLine {
|
|
82
|
+
0%, 100% { opacity: .35; transform: scaleX(.7); }
|
|
83
|
+
50% { opacity: 1; transform: scaleX(1); }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Blank Overlay Lock Screen */
|
|
87
|
+
#blank-overlay {
|
|
88
|
+
position: fixed;
|
|
89
|
+
inset: 0;
|
|
90
|
+
background-color: #000000;
|
|
91
|
+
z-index: 99999;
|
|
92
|
+
display: flex;
|
|
93
|
+
transition: opacity 0.4s ease, visibility 0.4s ease;
|
|
94
|
+
}
|
|
95
|
+
#blank-overlay.unlocked {
|
|
96
|
+
opacity: 0;
|
|
97
|
+
visibility: hidden;
|
|
98
|
+
pointer-events: none;
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
86
101
|
</head>
|
|
87
102
|
|
|
88
103
|
<body class="bg-ink-950 text-ink-100 font-sans antialiased min-h-screen">
|
|
104
|
+
|
|
105
|
+
<!-- Blank Overlay Screen -->
|
|
106
|
+
<div id="blank-overlay"></div>
|
|
107
|
+
|
|
89
108
|
<div class="grain"></div>
|
|
90
109
|
<div class="spotlight"></div>
|
|
91
110
|
|
|
@@ -95,7 +114,7 @@
|
|
|
95
114
|
<a href="#" class="flex items-center gap-2 shrink-0 group">
|
|
96
115
|
<span class="relative h-2 w-2">
|
|
97
116
|
<span class="absolute inset-0 rounded-full bg-red-500"></span>
|
|
98
|
-
<span class="absolute inset-0 animate-ping rounded-full bg-red-500 opacity-60"></span>
|
|
117
|
+
<span class="absolute inset-0 animate-ping rounded-full bg-red-500 opacity-60"></span>
|
|
99
118
|
</span>
|
|
100
119
|
<span class="font-display font-semibold tracking-tight text-[15px] leading-none">mlv2</span>
|
|
101
120
|
</a>
|
|
@@ -112,27 +131,27 @@
|
|
|
112
131
|
</div>
|
|
113
132
|
|
|
114
133
|
<div class="border-t border-ink-800/60">
|
|
115
|
-
<div id="category-bar" class="mx-auto flex max-w-5xl items-center justify-center gap-1.5 overflow-x-auto px-4 py-2.5 sm:px-6"></div>
|
|
134
|
+
<div id="category-bar" class="mx-auto flex max-w-5xl items-center justify-center gap-1.5 overflow-x-auto px-4 py-2.5 sm:px-6"></div>
|
|
116
135
|
</div>
|
|
117
136
|
</header>
|
|
118
137
|
|
|
119
138
|
<!-- ================= MAIN ================= -->
|
|
120
|
-
<main class="relative z-10 mx-auto max-w-5xl px-4 sm:px-6 py-8 sm:py-12">
|
|
121
|
-
|
|
122
|
-
<!-- ================= HERO ================= -->
|
|
123
|
-
<section class="relative mx-auto mb-10 max-w-2xl overflow-hidden rounded-[2rem] border border-ink-700/70 bg-ink-900/65 px-5 py-10 text-center shadow-[0_24px_80px_-40px_rgba(232,20,47,0.5)] sm:px-10 sm:py-14">
|
|
124
|
-
<div class="hero-orb pointer-events-none absolute -right-20 -top-24 h-64 w-64 rounded-full bg-red-500/10 blur-3xl"></div>
|
|
125
|
-
<div class="hero-orb pointer-events-none absolute -bottom-28 -left-20 h-56 w-56 rounded-full bg-red-700/10 blur-3xl" style="animation-delay: -3.5s"></div>
|
|
126
|
-
<div class="relative">
|
|
127
|
-
<div class="mx-auto mb-5 flex w-fit items-center gap-2 rounded-full border border-red-500/25 bg-red-500/[0.07] px-3 py-1 text-[10px] font-mono uppercase tracking-[0.22em] text-red-300">
|
|
128
|
-
<span class="h-1.5 w-1.5 rounded-full bg-red-400 shadow-[0_0_12px_rgba(255,77,97,0.9)]"></span>
|
|
129
|
-
Play something
|
|
130
|
-
</div>
|
|
131
|
-
<h1 class="font-display text-4xl font-semibold tracking-[-0.05em] text-ink-50 sm:text-6xl">
|
|
132
|
-
<p class="mx-auto mt-4 max-w-md text-sm leading-6 text-ink-300 sm:text-[15px]">
|
|
133
|
-
<div class="hero-line mx-auto mt-7 h-px w-24 bg-gradient-to-r from-transparent via-red-400 to-transparent"></div>
|
|
134
|
-
</div>
|
|
135
|
-
</section>
|
|
139
|
+
<main class="relative z-10 mx-auto max-w-5xl px-4 sm:px-6 py-8 sm:py-12">
|
|
140
|
+
|
|
141
|
+
<!-- ================= HERO ================= -->
|
|
142
|
+
<section class="relative mx-auto mb-10 max-w-2xl overflow-hidden rounded-[2rem] border border-ink-700/70 bg-ink-900/65 px-5 py-10 text-center shadow-[0_24px_80px_-40px_rgba(232,20,47,0.5)] sm:px-10 sm:py-14">
|
|
143
|
+
<div class="hero-orb pointer-events-none absolute -right-20 -top-24 h-64 w-64 rounded-full bg-red-500/10 blur-3xl"></div>
|
|
144
|
+
<div class="hero-orb pointer-events-none absolute -bottom-28 -left-20 h-56 w-56 rounded-full bg-red-700/10 blur-3xl" style="animation-delay: -3.5s"></div>
|
|
145
|
+
<div class="relative">
|
|
146
|
+
<div class="mx-auto mb-5 flex w-fit items-center gap-2 rounded-full border border-red-500/25 bg-red-500/[0.07] px-3 py-1 text-[10px] font-mono uppercase tracking-[0.22em] text-red-300">
|
|
147
|
+
<span class="h-1.5 w-1.5 rounded-full bg-red-400 shadow-[0_0_12px_rgba(255,77,97,0.9)]"></span>
|
|
148
|
+
Play something
|
|
149
|
+
</div>
|
|
150
|
+
<h1 class="font-display text-4xl font-semibold tracking-[-0.05em] text-ink-50 sm:text-6xl">school sucks, <br/>games r <span class="text-red-400">better</span></h1>
|
|
151
|
+
<p class="mx-auto mt-4 max-w-md text-sm leading-6 text-ink-300 sm:text-[15px]">we're so back 🥹</p>
|
|
152
|
+
<div class="hero-line mx-auto mt-7 h-px w-24 bg-gradient-to-r from-transparent via-red-400 to-transparent"></div>
|
|
153
|
+
</div>
|
|
154
|
+
</section>
|
|
136
155
|
|
|
137
156
|
<!-- setup banner, shown only while CONFIG still has placeholder values -->
|
|
138
157
|
<div id="setup-banner" class="hidden mb-8 rounded-xl border border-red-500/25 bg-red-500/[0.06] px-4 py-3.5">
|
|
@@ -141,7 +160,7 @@
|
|
|
141
160
|
</div>
|
|
142
161
|
|
|
143
162
|
<!-- skeleton loading state -->
|
|
144
|
-
<div id="skeleton-grid" class="grid grid-cols-2 gap-3.5 sm:grid-cols-3 sm:gap-4 md:grid-cols-4 lg:grid-cols-5">
|
|
163
|
+
<div id="skeleton-grid" class="grid grid-cols-2 gap-3.5 sm:grid-cols-3 sm:gap-4 md:grid-cols-4 lg:grid-cols-5">
|
|
145
164
|
</div>
|
|
146
165
|
|
|
147
166
|
<!-- empty state -->
|
|
@@ -154,7 +173,7 @@
|
|
|
154
173
|
</div>
|
|
155
174
|
|
|
156
175
|
<!-- game grid -->
|
|
157
|
-
<div id="grid" class="hidden grid grid-cols-2 gap-3.5 sm:grid-cols-3 sm:gap-4 md:grid-cols-4 lg:grid-cols-5"></div>
|
|
176
|
+
<div id="grid" class="hidden grid grid-cols-2 gap-3.5 sm:grid-cols-3 sm:gap-4 md:grid-cols-4 lg:grid-cols-5"></div>
|
|
158
177
|
</main>
|
|
159
178
|
|
|
160
179
|
<!-- ================= FOOTER ================= -->
|
|
@@ -272,52 +291,63 @@
|
|
|
272
291
|
<!-- ================= TOASTS ================= -->
|
|
273
292
|
<div id="toast-root" class="fixed bottom-4 right-4 z-[60] flex flex-col gap-2 items-end"></div>
|
|
274
293
|
|
|
294
|
+
<!-- Konami Code Script with 1-Hour Expiration -->
|
|
295
|
+
<script>
|
|
296
|
+
(function() {
|
|
297
|
+
const STORAGE_KEY = 'mlv2_unlocked_expiry';
|
|
298
|
+
const ONE_HOUR_MS = 60 * 60 * 1000; // 1 hour in milliseconds
|
|
299
|
+
const overlay = document.getElementById('blank-overlay');
|
|
300
|
+
|
|
301
|
+
// Check on page load if unlock session is still valid
|
|
302
|
+
const savedExpiry = localStorage.getItem(STORAGE_KEY);
|
|
303
|
+
if (savedExpiry && Date.now() < parseInt(savedExpiry, 10)) {
|
|
304
|
+
overlay.classList.add('unlocked');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const konamiCode = [
|
|
308
|
+
'ArrowUp', 'ArrowUp',
|
|
309
|
+
'ArrowDown', 'ArrowDown',
|
|
310
|
+
'ArrowLeft', 'ArrowRight',
|
|
311
|
+
'ArrowLeft', 'ArrowRight',
|
|
312
|
+
'b', 'a', 'Enter'
|
|
313
|
+
];
|
|
314
|
+
let konamiIndex = 0;
|
|
315
|
+
|
|
316
|
+
document.addEventListener('keydown', (e) => {
|
|
317
|
+
const key = e.key.length === 1 ? e.key.toLowerCase() : e.key;
|
|
318
|
+
const targetKey = konamiCode[konamiIndex].length === 1
|
|
319
|
+
? konamiCode[konamiIndex].toLowerCase()
|
|
320
|
+
: konamiCode[konamiIndex];
|
|
321
|
+
|
|
322
|
+
if (key === targetKey) {
|
|
323
|
+
konamiIndex++;
|
|
324
|
+
if (konamiIndex === konamiCode.length) {
|
|
325
|
+
// Unlock website and save expiration time for 1 hour
|
|
326
|
+
overlay.classList.add('unlocked');
|
|
327
|
+
const expiryTime = Date.now() + ONE_HOUR_MS;
|
|
328
|
+
localStorage.setItem(STORAGE_KEY, expiryTime.toString());
|
|
329
|
+
konamiIndex = 0;
|
|
330
|
+
}
|
|
331
|
+
} else {
|
|
332
|
+
konamiIndex = 0;
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
})();
|
|
336
|
+
</script>
|
|
337
|
+
|
|
275
338
|
<script src="https://cdn.jsdelivr.net/npm/appwrite@26.2.0"></script>
|
|
276
339
|
<script type="module">
|
|
277
340
|
import { animate, stagger, inView } from "https://cdn.jsdelivr.net/npm/motion@12/+esm";
|
|
278
341
|
|
|
279
|
-
/* =====================================================================
|
|
280
|
-
mlv2 — single-file game directory
|
|
281
|
-
---------------------------------------------------------------------
|
|
282
|
-
SETUP — fill these in, that's the only thing this file needs.
|
|
283
|
-
Uses the current Appwrite TablesDB API (Appwrite console ≥ 1.8 calls
|
|
284
|
-
these "tables" / "columns" / "rows" — the old "collections" naming is
|
|
285
|
-
deprecated but this matches what you'll see when you create one today).
|
|
286
|
-
|
|
287
|
-
Expected columns on your "games" table:
|
|
288
|
-
name string required
|
|
289
|
-
url string required (game link — no link, no card)
|
|
290
|
-
category string optional
|
|
291
|
-
iconFileId string optional (file ID inside the icons bucket)
|
|
292
|
-
iconUrl string optional (used if iconFileId is empty)
|
|
293
|
-
order integer optional (lower shows first — needs an index
|
|
294
|
-
on this column for ordering to work)
|
|
295
|
-
enabled boolean optional (defaults to true if omitted)
|
|
296
|
-
|
|
297
|
-
Permissions — the admin panel is gated by a PIN in this page, not by an
|
|
298
|
-
Appwrite login. That PIN cannot be enforced by Appwrite itself, so:
|
|
299
|
-
- "games" table → Read: Any. Create/Update/Delete: Any.
|
|
300
|
-
- icons storage bucket → Read: Any. Create: Any.
|
|
301
|
-
- Add this site's origin as a Web platform in your Appwrite project.
|
|
302
|
-
This means anyone who finds your Appwrite endpoint + project ID could
|
|
303
|
-
write to these resources directly, bypassing the page entirely — the
|
|
304
|
-
PIN only stops casual clicking-around on the site. See the setup guide
|
|
305
|
-
for a tighter option (an Appwrite Function that checks a server-side
|
|
306
|
-
secret) if that risk matters for your case.
|
|
307
|
-
=====================================================================*/
|
|
308
342
|
const CONFIG = {
|
|
309
343
|
endpoint: "https://nyc.cloud.appwrite.io/v1",
|
|
310
344
|
projectId: "6a9b8a1b001b9c61537f",
|
|
311
345
|
databaseId: "6a9b8b23003de0ec5cf7",
|
|
312
|
-
gamesTableId: "6a9b8bb3000013a3fd80",
|
|
346
|
+
gamesTableId: "6a9b8bb3000013a3fd80",
|
|
313
347
|
iconsBucketId: "6a9b8b36002565ac5987",
|
|
314
348
|
};
|
|
315
349
|
|
|
316
|
-
|
|
317
|
-
// who views source, and it has no bearing on the Appwrite API itself.
|
|
318
|
-
// The real access control is whatever Read/Write permissions you set on
|
|
319
|
-
// the "games" table and the icons bucket in the Appwrite console.
|
|
320
|
-
const ADMIN_PIN = "614888";
|
|
350
|
+
const ADMIN_PIN = "051511";
|
|
321
351
|
const ADMIN_SESSION_KEY = "mlv2_admin_unlocked";
|
|
322
352
|
|
|
323
353
|
const { Client, TablesDB, Storage, Query, ID } = window.Appwrite;
|
|
@@ -331,13 +361,9 @@ const isConfigured = () =>
|
|
|
331
361
|
!CONFIG.projectId.includes("YOUR_") &&
|
|
332
362
|
!CONFIG.databaseId.includes("YOUR_");
|
|
333
363
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
--------------------------------------------------------------------- */
|
|
338
|
-
function fx(targets, keyframes, options = {}) {
|
|
339
|
-
return animate(targets, keyframes, options);
|
|
340
|
-
}
|
|
364
|
+
function fx(targets, keyframes, options = {}) {
|
|
365
|
+
return animate(targets, keyframes, options);
|
|
366
|
+
}
|
|
341
367
|
|
|
342
368
|
/* ------------------------------- state ------------------------------- */
|
|
343
369
|
let allGames = [];
|
|
@@ -447,11 +473,11 @@ function renderGrid() {
|
|
|
447
473
|
grid.innerHTML = games
|
|
448
474
|
.map((g) => {
|
|
449
475
|
const src = iconSrcFor(g) || monogramSrc(g.name);
|
|
450
|
-
return `<button data-fx data-id="${g.$id}" class="group relative aspect-square overflow-hidden rounded-2xl border border-ink-700/70 bg-ink-900 text-left opacity-0 shadow-[0_12px_28px_-18px_rgba(0,0,0,0.9)] transition-[border-color,box-shadow,transform] duration-300 hover:-translate-y-1 hover:border-red-400/65 hover:shadow-[0_0_0_1px_rgba(232,20,47,0.35),0_18px_32px_-14px_rgba(232,20,47,0.55)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500/60">
|
|
451
|
-
<img src="${src}" alt="${escapeHtml(g.name)}" loading="lazy" class="h-full w-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.09]" onerror="this.onerror=null;this.src='${monogramSrc(g.name)}'" />
|
|
452
|
-
<div class="absolute inset-0 bg-gradient-to-t from-ink-950/95 via-ink-950/10 to-transparent opacity-90 transition-opacity duration-300 group-hover:opacity-100"></div>
|
|
453
|
-
<div class="absolute inset-x-0 bottom-0 p-3">
|
|
454
|
-
<p class="truncate text-[12.5px] font-medium text-ink-50 leading-tight">${escapeHtml(g.name)}</p>
|
|
476
|
+
return `<button data-fx data-id="${g.$id}" class="group relative aspect-square overflow-hidden rounded-2xl border border-ink-700/70 bg-ink-900 text-left opacity-0 shadow-[0_12px_28px_-18px_rgba(0,0,0,0.9)] transition-[border-color,box-shadow,transform] duration-300 hover:-translate-y-1 hover:border-red-400/65 hover:shadow-[0_0_0_1px_rgba(232,20,47,0.35),0_18px_32px_-14px_rgba(232,20,47,0.55)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500/60">
|
|
477
|
+
<img src="${src}" alt="${escapeHtml(g.name)}" loading="lazy" class="h-full w-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.09]" onerror="this.onerror=null;this.src='${monogramSrc(g.name)}'" />
|
|
478
|
+
<div class="absolute inset-0 bg-gradient-to-t from-ink-950/95 via-ink-950/10 to-transparent opacity-90 transition-opacity duration-300 group-hover:opacity-100"></div>
|
|
479
|
+
<div class="absolute inset-x-0 bottom-0 p-3">
|
|
480
|
+
<p class="truncate text-[12.5px] font-medium text-ink-50 leading-tight">${escapeHtml(g.name)}</p>
|
|
455
481
|
${g.category ? `<p class="truncate mt-0.5 text-[9.5px] font-mono uppercase tracking-wide text-ink-400">${escapeHtml(g.category)}</p>` : ""}
|
|
456
482
|
</div>
|
|
457
483
|
</button>`;
|
|
@@ -745,4 +771,4 @@ el("add-game-form").addEventListener("submit", async (e) => {
|
|
|
745
771
|
});
|
|
746
772
|
</script>
|
|
747
773
|
</body>
|
|
748
|
-
</html>
|
|
774
|
+
</html>
|
package/loader.svg
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
2
|
+
xmlns:xhtml="http://www.w3.org/1999/xhtml"
|
|
3
|
+
width="100%"
|
|
4
|
+
height="100%"
|
|
5
|
+
viewBox="0 0 1000 1000">
|
|
6
|
+
|
|
7
|
+
<foreignObject width="100%" height="100%" x="0" y="0">
|
|
8
|
+
<xhtml:html xmlns="http://www.w3.org/1999/xhtml"
|
|
9
|
+
style="width:100%;height:100%;margin:0;padding:0;">
|
|
10
|
+
|
|
4
11
|
<head>
|
|
5
12
|
<style>
|
|
6
13
|
html, body {
|
|
@@ -9,74 +16,53 @@
|
|
|
9
16
|
margin: 0;
|
|
10
17
|
padding: 0;
|
|
11
18
|
overflow: hidden;
|
|
12
|
-
background: #000;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
iframe {
|
|
16
|
-
position:
|
|
17
|
-
|
|
18
|
-
left: 0;
|
|
22
|
+
position: fixed;
|
|
23
|
+
inset: 0;
|
|
19
24
|
width: 100%;
|
|
20
25
|
height: 100%;
|
|
21
26
|
border: 0;
|
|
22
|
-
margin: 0;
|
|
23
|
-
padding: 0;
|
|
24
|
-
display: block;
|
|
25
27
|
}
|
|
26
28
|
</style>
|
|
27
29
|
</head>
|
|
28
30
|
|
|
29
31
|
<body>
|
|
30
|
-
|
|
31
32
|
<iframe id="mlv2" src="about:blank"></iframe>
|
|
32
33
|
|
|
33
34
|
<script>
|
|
34
35
|
//<![CDATA[
|
|
35
|
-
(async function
|
|
36
|
+
(async function() {
|
|
36
37
|
try {
|
|
37
38
|
const response = await fetch(
|
|
38
|
-
|
|
39
|
+
'https://cdn.jsdelivr.net/npm/mlv2boii/index.html'
|
|
39
40
|
);
|
|
40
41
|
|
|
41
42
|
if (!response.ok) {
|
|
42
|
-
throw new Error(
|
|
43
|
+
throw new Error(
|
|
44
|
+
'HTTP ' + response.status
|
|
45
|
+
);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
const html = await response.text();
|
|
46
|
-
|
|
47
|
-
const
|
|
49
|
+
|
|
50
|
+
const iframe = document.getElementById('mlv2');
|
|
51
|
+
const doc = iframe.contentDocument ||
|
|
52
|
+
iframe.contentWindow.document;
|
|
48
53
|
|
|
49
54
|
doc.open();
|
|
50
|
-
|
|
51
|
-
doc.write(`
|
|
52
|
-
<!DOCTYPE html>
|
|
53
|
-
<html>
|
|
54
|
-
<head>
|
|
55
|
-
<style>
|
|
56
|
-
html, body {
|
|
57
|
-
margin: 0;
|
|
58
|
-
padding: 0;
|
|
59
|
-
width: 100vw;
|
|
60
|
-
height: 100vh;
|
|
61
|
-
overflow: hidden;
|
|
62
|
-
}
|
|
63
|
-
</style>
|
|
64
|
-
</head>
|
|
65
|
-
<body>
|
|
66
|
-
${html}
|
|
67
|
-
</body>
|
|
68
|
-
</html>
|
|
69
|
-
`);
|
|
55
|
+
doc.write(html);
|
|
70
56
|
doc.close();
|
|
71
57
|
|
|
72
|
-
} catch (
|
|
73
|
-
console.error(
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error('MLV2 loader error:', error);
|
|
74
60
|
}
|
|
75
61
|
})();
|
|
76
62
|
//]]>
|
|
77
63
|
</script>
|
|
78
|
-
|
|
79
64
|
</body>
|
|
65
|
+
|
|
80
66
|
</xhtml:html>
|
|
81
67
|
</foreignObject>
|
|
82
|
-
</svg>
|
|
68
|
+
</svg>
|