PageSourceSearch

https://reader.easeverse.ink/demo/romeo-juliet

html easeverse.ink collected 2026-10-02 01:57:01 UTC 6,443 bytes, 115 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5    <meta charset="UTF-8" />
6    
6<script>
7        // Self-heal: when an /assets/* script fails to load (typically CDN
8        // cache poisoning where the path returns text/html SPA fallback
9        // during deploy transitions, or a stale chunk hash from cached
10        // index.html), force-refetch the asset bypassing disk cache then
11        // reload the page. Capped at 2 attempts per session via
12        // sessionStorage to prevent infinite reload loops. Must be inline
13        // and first in <head> so the listener is registered before any
14        // module starts loading.
15        (function () {
16            var KEY = '__reader_heal_count';
17            var healed = false;
18            // Fire-and-forget telemetry to /error-report. keepalive lets the
19            // POST complete after the location.reload that follows. JWT is
20            // attached if present so user_id gets correlated server-side.
21            function reportHeal(assetUrl, attempt, action) {
22                try {
23                    var token = null;
24                    try { token = localStorage.getItem('easeverse_token'); } catch (_) {}
25                    var headers = { 'Content-Type': 'application/json' };
26                    if (token) headers['Authorization'] = 'Bearer ' + token;
27                    fetch('https://api.easeverse.ink/error-report', {
28                        method: 'POST',
29                        headers: headers,
30                        body: JSON.stringify({
31                            client: 'reader',
32                            level: action === 'give-up' ? 'warn' : 'info',
33                            message: action === 'give-up'
34                                ? 'self-heal limit reached, gave up at attempt ' + attempt
35                                : 'self-heal triggered (attempt ' + attempt + ')',
36                            url: location.href,
37                            metadata: {
38                                source: 'self-heal',
39                                action: action,
40                                path: assetUrl,
41                            },
42                        }),
43                        keepalive: true,
44                    }).catch(function () {});
45                } catch (_e) {}
46            }
47            window.addEventListener('error', function (e) {
48                if (healed) return;
49                var t = e && e.target;
50                if (!t) return;
51                if (t.tagName !== 'SCRIPT' && t.tagName !== 'LINK') return;
52                var url = t.src || t.href || '';
53                if (url.indexOf('/assets/') === -1) return;
54                var count = parseInt(sessionStorage.getItem(KEY) || '0', 10);
55                if (count >= 2) {
56                    console.warn('[reader] heal limit reached, giving up');
57                    reportHeal(url, count, 'give-up');
58                    return;
59                }
60                healed = true;
61                var nextAttempt = count + 1;
62                sessionStorage.setItem(KEY, String(nextAttempt));
63                console.warn('[reader] asset load failure, refreshing cache:', url);
64                reportHeal(url, nextAttempt, 'trigger');
65                var done = function () { window.location.reload(); };
66                try {
67                    fetch(url, { cache: 'reload', credentials: 'same-origin' })
68                        .then(done, done);
69                } catch (_e) {
70                    done();
71                }
72            }, true);
73            window.addEventListener('load', function () {
74                setTimeout(function () {
75                    if (!healed) sessionStorage.removeItem(KEY);
76                }, 3000);
77            });
78        })();
79    </script>
79
80    <link rel="icon" type="image/jpeg" href="/EaseVerse_Reader_ClassicBlue_Depth_v3.jpg?v=1" sizes="32x32" />
81    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
82    <!-- Mobile-optimized signal for Xiaomi/Huawei in-app browsers — without
83         these, those browsers force-scale fonts < 12px and break rem layout. -->
84    <meta name="HandheldFriendly" content="true" />
85    <meta name="MobileOptimized" content="width" />
86    <!-- Static first-paint fallback; JS replaces document.title with the
87         language-specific value in src/lib/i18n.js on module load. -->
88    <meta name="description" content="EaseVerse Reader | Multilingual Deep Reading" />
89    <title>EaseVerse Reader | Multilingual Deep Reading</title>
90
91    <!-- Preload fonts -->
92    <link rel="preconnect" href="https://fonts.googleapis.com">
93    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
94    <link
95        href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+SC:wght@400;500;600;700&family=Literata:ital,opsz,wght@0,7..72,200..900;1,7..72,200..900&family=Source+Sans+3:wght@300;400;500;600&family=Roboto:wght@300;400;500;700&family=Poppins:wght@300;400;500;600&family=Mulish:wght@300;400;500;600;700&family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&family=PT+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap"
96        rel="stylesheet">
97    <!-- Do NOT add crossorigin="anonymous" here. Google's gsi/client endpoint
98         returns no Access-Control-Allow-Origin header, so the browser would
99         block the script entirely (ERR_FAILED) and the Sign-In button would
100         never render. The cost is that any gsi-internal errors arrive as
101         opaque "Script error." with no stack — handled (filtered) in
102         src/lib/error-reporter.js to keep that noise out of the DB. -->
103    
103<script src="https://accounts.google.com/gsi/client" async></script>
103
104  
104<script type="module" crossorigin src="/assets/index-CGi0bt1A.js"></script>
104
105  <link rel="modulepreload" crossorigin href="/assets/react-D88zDUjx.js">
106  <link rel="modulepreload" crossorigin href="/assets/epub-iBTXOzSI.js">
107  <link rel="stylesheet" crossorigin href="/assets/index-BPp4UNtk.css">
108</head>
109
110<body>
111    <div id="root"></div>
112<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"9ea5289a55fd4c5c8f88b225f468fe34","r":1,"spa":2}' crossorigin="anonymous"></script>
112
113</body>
114
115</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.