PageSourceSearch

https://mychara.ai/about

html mychara.ai collected 2026-10-05 15:15:01 UTC 29,883 bytes, 782 lines download raw bytes

1<!doctype html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <meta name="theme-color" content="#EBD3BC" />
7    <meta name="description" content="MyChara is a service for publishing an AI Chara setup as a creative work and then talking with that Chara. This page explains who creates the public material, where AI is used, an…" />
8    <meta name="msvalidate.01" content="18CB8C6BC3D06889BA248A82DC9AF1F6" />
9    <meta name="mobile-web-app-capable" content="yes" />
10    <meta name="apple-mobile-web-app-capable" content="yes" />
11    <meta name="apple-mobile-web-app-status-bar-style" content="default" />
12    <meta name="apple-mobile-web-app-title" content="MyChara" />
13    <title>AI Chara creation and conversation on MyChara — MyChara</title>
14
15    
15<script>
16      (() => {
17        const devHosts = {
18          main: 'dev.mychara.ai',
19          plans: 'dev.plans.mychara.ai',
20          charge: 'dev.charge.mychara.ai',
21          planPayment: 'dev.plan-payment.mychara.ai',
22          chargePayment: 'dev.charge-payment.mychara.ai',
23        };
24        const prodHosts = {
25          main: 'mychara.ai',
26          plans: 'plans.mychara.ai',
27          charge: 'charge.mychara.ai',
28          planPayment: 'plan-payment.mychara.ai',
29          chargePayment: 'charge-payment.mychara.ai',
30        };
31        const billingOnlyDevHosts = [
32          devHosts.plans,
33          devHosts.charge,
34          devHosts.planPayment,
35          devHosts.chargePayment,
36        ];
37        const billingOnlyProdHosts = [
38          prodHosts.plans,
39          prodHosts.charge,
40          prodHosts.planPayment,
41          prodHosts.chargePayment,
42        ];
43        const hosts = billingOnlyDevHosts.includes(location.hostname)
44          ? devHosts
45          : billingOnlyProdHosts.includes(location.hostname)
46            ? prodHosts
47            : null;
48
49        if (hosts === null || location.pathname === '/') return;
50
51        const url = new URL(location.href);
52        url.port = '';
53
54        if (location.pathname === '/plans') {
55          url.hostname = hosts.plans;
56          url.pathname = '/';
57        } else if (location.pathname === '/charge') {
58          url.hostname = hosts.charge;
59          url.pathname = '/';
60        } else if (location.pathname === '/billing/plan-payment') {
61          url.hostname = hosts.planPayment;
62          url.pathname = '/';
63        } else if (location.pathname === '/billing/charge-payment') {
64          url.hostname = hosts.chargePayment;
65          url.pathname = '/';
66        } else {
67          url.hostname = hosts.main;
68        }
69
70        location.replace(url);
71      })();
72    </script>
72
73
74    <!--
75      Warm up TLS to the API origin before the SPA bundle parses and
76      issues its first /api/charas fetch. Saves ~200-400 ms on
77      cold mobile networks where DNS + TLS is the long pole. `crossorigin`
78      is required because API calls send credentials (cookies). Failure
79      is silent — preconnect is a hint, not a load.
80    -->
81    <link rel="preconnect" href="https://api.mychara.ai" crossorigin />
82    <link rel="dns-prefetch" href="https://api.mychara.ai" />
83
84    <link rel="icon" href="/favicon.ico" sizes="any" />
85    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png" />
86    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
87    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
88    <link rel="apple-touch-icon-precomposed" sizes="180x180" href="/apple-touch-icon.png" />
89    <link rel="manifest" href="/manifest.webmanifest" />
90    <link rel="canonical" href="https://mychara.ai/about" />
91    <style>
92      html,
93      body,
94      #root {
95        margin: 0;
96        min-height: 100%;
97      }
98
99      body {
100        background: #0a0f12;
101      }
102
103      .app-startup-loading {
104        min-height: 100vh;
105        min-height: 100dvh;
106        display: grid;
107        place-items: start center;
108        padding: max(24px, env(safe-area-inset-top)) 24px max(24px, env(safe-area-inset-bottom));
109        box-sizing: border-box;
110        color: #f8fafc;
111        background: #0a0f12;
112        font-family:
113          -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', 'Hiragino Sans',
114          'Noto Sans JP', 'Yu Gothic Medium', 'Segoe UI', system-ui, sans-serif;
115      }
116
117      .app-startup-loading *,
118      .app-startup-loading *::before,
119      .app-startup-loading *::after {
120        box-sizing: border-box;
121      }
122
123      .app-startup-loading__content {
124        display: flex;
125        flex-direction: column;
126        align-items: center;
127        gap: 16px;
128        width: min(100%, 760px);
129        padding-top: clamp(32px, 8vh, 64px);
130      }
131
132      .app-startup-loading__brand {
133        display: inline-flex;
134        align-items: center;
135        gap: 10px;
136        color: #f8fafc;
137        font-size: 20px;
138        font-weight: 700;
139        line-height: 1;
140        letter-spacing: 0;
141      }
142
143      .app-startup-loading__logo {
144        width: 36px;
145        height: 36px;
146        flex: 0 0 auto;
147      }
148
149      .app-startup-loading__wordmark {
150        transform: translateY(1px);
151      }
152
153      .app-startup-loading__spinner {
154        width: 40px;
155        height: 40px;
156        border: 3px solid rgba(255, 255, 255, 0.14);
157        border-top-color: #10b981;
158        border-radius: 50%;
159        animation: app-startup-spin 0.8s linear infinite;
160      }
161
162      .app-startup-loading__message {
163        margin: 0;
164        color: #a7b4bd;
165        font-size: 14px;
166        font-weight: 600;
167        line-height: 1.4;
168        letter-spacing: 0;
169      }
170
171      .app-startup-loading__recovery {
172        display: flex;
173        flex-direction: column;
174        align-items: center;
175        gap: 12px;
176        width: min(100%, 440px);
177        text-align: center;
178      }
179
180      .app-startup-loading__recovery[hidden],
181      .app-startup-loading__spinner[hidden] {
182        display: none;
183      }
184
185      .app-startup-loading__retry {
186        display: inline-flex;
187        min-height: 44px;
188        align-items: center;
189        justify-content: center;
190        border: 0;
191        border-radius: 8px;
192        padding: 10px 28px;
193        background: #10b981;
194        color: #07120e;
195        font-size: 14px;
196        font-weight: 800;
197        text-decoration: none;
198      }
199
200      .app-startup-loading__external-hint {
201        margin: 0;
202        color: #a7b4bd;
203        font-size: 13px;
204        line-height: 1.7;
205      }
206
207      .app-startup-loading__copy {
208        appearance: none;
209        border: 0;
210        padding: 8px 12px;
211        background: transparent;
212        color: #86efac;
213        font-size: 13px;
214        font-weight: 700;
215        text-decoration: underline;
216        text-underline-offset: 3px;
217      }
218
219      .app-crawlable-content {
220        width: 100%;
221        margin-top: 4px;
222        color: #d9e5ea;
223        text-align: left;
224        font-size: 14px;
225        line-height: 1.75;
226      }
227
228      .app-crawlable-content__article {
229        width: 100%;
230      }
231
232      .app-crawlable-content__eyebrow {
233        margin: 0 0 4px;
234        color: #86efac;
235        font-size: 12px;
236        font-weight: 800;
237        letter-spacing: 0;
238      }
239
240      .app-crawlable-content h1 {
241        margin: 0 0 10px;
242        color: #f8fafc;
243        font-size: 20px;
244        font-weight: 800;
245        line-height: 1.35;
246        letter-spacing: 0;
247      }
248
249      .app-crawlable-content p {
250        margin: 8px 0 0;
251      }
252
253      .app-crawlable-content ul {
254        margin: 12px 0 0;
255        padding-left: 1.25em;
256      }
257
258      .app-crawlable-content li + li {
259        margin-top: 4px;
260      }
261
262      .app-crawlable-content__links {
263        display: flex;
264        flex-wrap: wrap;
265        gap: 8px 12px;
266        padding-left: 0;
267        list-style: none;
268      }
269
270      .app-crawlable-content__links a {
271        color: #86efac;
272        font-weight: 700;
273        text-decoration-thickness: 1px;
274        text-underline-offset: 3px;
275      }
276
277      @keyframes app-startup-spin {
278        to {
279          transform: rotate(360deg);
280        }
281      }
282
283      @media (prefers-reduced-motion: reduce) {
284        .app-startup-loading__spinner {
285          animation: none;
286          border-color: rgba(255, 255, 255, 0.14);
287          border-top-color: #10b981;
288        }
289      }
290    </style>
291
292    <!--
293      Default Open Graph / Twitter Card tags. Per-page tags for
294      /chara/:id and /users/:userId are rewritten at the edge by
295      the Cloudflare Pages Functions under `functions/` — those tags
296      override these defaults for crawlers that don't execute JS
297      (Facebook, X, LINE, Discord, Slack, etc.).
298    -->
299    <meta property="og:type" content="website" />
300    <meta property="og:site_name" content="MyChara" />
301    <meta property="og:locale" content="ja_JP" />
302    <meta property="og:title" content="AI Chara creation and conversation on MyChara — MyChara" />
303    <meta property="og:description" content="MyChara is a service for publishing an AI Chara setup as a creative work and then talking with that Chara. This page explains who creates the public material, where AI is used, an…" />
304    <meta property="og:url" content="https://mychara.ai/about" />
305    <meta property="og:image" content="https://mychara.ai/ogp-default.png" />
306    <meta property="og:image:width" content="1200" />
307    <meta property="og:image:height" content="630" />
308    <meta property="og:image:alt" content="MyChara" />
309    <meta name="twitter:card" content="summary_large_image" />
310    <meta name="twitter:site" content="@MyCharaAI" />
311    <meta name="twitter:title" content="AI Chara creation and conversation on MyChara — MyChara" />
312    <meta name="twitter:description" content="MyChara is a service for publishing an AI Chara setup as a creative work and then talking with that Chara. This page explains who creates the public material, where AI is used, an…" />
313    <meta name="twitter:image" content="https://mychara.ai/ogp-default.png" />
314
315    <!--
316      JSON-LD: Organization + WebSite. Helps Google understand the
317      site identity and surface the sitelinks search box once the
318      domain has reputation. Per-page Person / ProfilePage records
319      are injected by the Pages Functions for /chara/:id and
320      /users/:userId.
321    -->
322    
322<script type="application/ld+json">
323      {
324        "@context": "https://schema.org",
325        "@graph": [
326          {
327            "@type": "Organization",
328            "@id": "https://mychara.ai/#org",
329            "name": "MyChara",
330            "url": "https://mychara.ai",
331            "logo": "https://mychara.ai/logo-512.png",
332            "sameAs": ["https://x.com/MyCharaAI"]
333          },
334          {
335            "@type": "WebSite",
336            "@id": "https://mychara.ai/#site",
337            "url": "https://mychara.ai",
338            "name": "MyChara",
339            "publisher": { "@id": "https://mychara.ai/#org" },
340            "inLanguage": "ja",
341            "potentialAction": {
342              "@type": "SearchAction",
343              "target": {
344                "@type": "EntryPoint",
345                "urlTemplate": "https://mychara.ai/search?q={search_term_string}"
346              },
347              "query-input": "required name=search_term_string"
348            }
349          }
350        ]
351      }
352    </script>
352
353
354    <!-- AdSense site verification / Auto ads loader. -->
355    
355<script
356      async
357      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8347367683271780"
358      crossorigin="anonymous"
359    ></script>
359
360    
360<script id="app-main-module" onload="window.__MYCHARA_BOOT__ &amp;&amp; window.__MYCHARA_BOOT__.mark('app_boot_module_loaded')" onerror="window.__MYCHARA_BOOT__ &amp;&amp; window.__MYCHARA_BOOT__.fail('app_boot_module_error', { error_kind: 'main_module_resource_error' })" type="module" crossorigin src="/assets/index-B04v8a-s.js"></script>
360
361  </head>
362  <body>
363    <div id="root">
364      <div
365        class="app-startup-loading"
366        role="status"
367        aria-live="polite"
368        aria-busy="true"
369        aria-label="Loading"
370      >
371        <div class="app-startup-loading__content">
372          <span class="app-startup-loading__brand" aria-hidden="true">
373            <svg
374              class="app-startup-loading__logo"
375              viewBox="0 0 32 32"
376              xmlns="http://www.w3.org/2000/svg"
377              focusable="false"
378            >
379              <circle cx="16" cy="16" r="14" fill="#10b981"></circle>
380              <path
381                d="M10 13 Q10 10 13 10 L19 10 Q22 10 22 13 L22 17 Q22 20 19 20 L14 20 L10 23 Z"
382                fill="#0a0f12"
383              ></path>
384              <circle cx="14" cy="15" r="1.3" fill="#ffffff"></circle>
385              <circle cx="18" cy="15" r="1.3" fill="#ffffff"></circle>
386            </svg>
387            <span class="app-startup-loading__wordmark">MyChara</span>
388          </span>
389          <span class="app-startup-loading__spinner" aria-hidden="true"></span>
390          <p class="app-startup-loading__message">Fetching data…</p>
391          <div class="app-startup-loading__recovery" hidden>
392            <a class="app-startup-loading__retry" href="">再試行</a>
393            <p class="app-startup-loading__external-hint">
394              Xアプリ内で繰り返し失敗する場合は、右上のメニューからSafariまたはChromeで開いてください。
395            </p>
396            <button class="app-startup-loading__copy" type="button">現在のURLをコピー</button>
397          </div>
398          <section id="app-crawlable-content" class="app-crawlable-content" aria-label="About MyChara"><article class="app-crawlable-content__article">
399      <p class="app-crawlable-content__eyebrow">About MyChara</p>
400      <h1>AI Chara creation and conversation on MyChara</h1>
401      <p>MyChara is a service for publishing an AI Chara setup as a creative work and then talking with that Chara. This page explains who creates the public material, where AI is used, and what the operator provides.</p>
402<p>What the service is for</p>
403<p>MyChara is built around reading a setup before choosing to talk. A public Chara page carries a name, introduction, basic setting, main Chara profile, opening message, and tags, so a reader can understand the scene and relationship before starting a conversation.</p>
404<p>Public pages can be read without signing in. An account adds saved conversations and creation tools for Charas, voices, replays, and world settings. Every post can be public, unlisted, invite-only, or private.</p>
405<p>Who creates public material</p>
406<p>The name, description, setup, opening message, images, and tags on a public Chara are created and published by its author. MyChara provides the publishing and reading system; the operator does not create every Chara. Except for anonymous posts, public pages link back to the author.</p>
407<p>Published material can be edited later, and its visibility can also be changed. Public pages are designed to show the information that a conversation depends on before the reader decides to begin.</p>
408<p>Where AI is used</p>
409<p>The setup and opening message shown on a public page are material saved and published by the author. After a conversation starts, AI generates replies from that setup, the opening message, and the user’s messages. The same Chara can respond differently as the conversation changes.</p>
410<p>AI replies are for creative conversation, not a replacement for fact-checking or professional judgement. MyChara treats reading a published setup and reading generated conversation as distinct activities.</p>
411<p>Operator and contact</p>
412<p>MyChara is operated by MyChara Inc. Service behaviour, pricing, and the handling of posted material are described on the public pages, in the terms of use, the privacy policy, and the legal information page.</p>
413<p>Questions about faults, rights, or public material can be sent to <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cbb8bebbbba4b9bf8ba6b2a8a3aab9aae5aaa2">[email&#160;protected]</a>.</p>
414      
415      <nav aria-label="Links to public pages">
416        <ul class="app-crawlable-content__links">
417          <li><a href="/guides/create">
417AI Chara creation guide</a></li>
418          <li><a href="/">Home</a></li>
419          <li><a href="/terms">Terms of Service</a></li>
420          <li><a href="/privacy">Privacy Policy</a></li>
421        </ul>
422      </nav>
423    </article></section>
424        </div>
425      </div>
426    </div>
vendor: 113 bytes, lines 426-427
426
427    <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
427<script id="app-boot-monitor">
428      (function () {
429        var API_URL = 'https://api.mychara.ai/api/product-analytics/events';
430        var TIMEOUT_MS = 9000;
431        var ALLOWED_PARAMS = [
432          'utm_source',
433          'utm_medium',
434          'utm_campaign',
435          'utm_term',
436          'utm_content',
437          'mc_test',
438          'mc_entry',
439          'mc_lang',
440          'mc_gender',
441          'mc_chara',
442          'from',
443          'type',
444          'kenzen',
445        ];
446        var COPY = {
447          ja: {
448            failed: '読み込みに失敗しました',
449            retry: '再試行',
450            retrying: '再試行しています…',
451            hint: 'Xアプリ内で繰り返し失敗する場合は、右上のメニューからSafariまたはChromeで開いてください。',
452            copy: '現在のURLをコピー',
453            copied: 'URLをコピーしました',
454          },
455          en: {
456            failed: 'Failed to load this page',
457            retry: 'Try again',
458            retrying: 'Trying again…',
459            hint: 'If this keeps failing inside X, use the top-right menu to open the page in Safari or Chrome.',
460            copy: 'Copy current URL',
461            copied: 'URL copied',
462          },
463          'zh-CN': {
464            failed: '页面加载失败',
465            retry: '重试',
466            retrying: '正在重试…',
467            hint: '如果在 X 应用内反复失败,请从右上角菜单使用 Safari 或 Chrome 打开。',
468            copy: '复制当前网址',
469            copied: '网址已复制',
470          },
471          'zh-TW': {
472            failed: '頁面載入失敗',
473            retry: '重試',
474            retrying: '正在重試…',
475            hint: '如果在 X 應用程式內反覆失敗,請從右上角選單使用 Safari 或 Chrome 開啟。',
476            copy: '複製目前網址',
477            copied: '網址已複製',
478          },
479          ko: {
480            failed: '페이지를 불러오지 못했습니다',
481            retry: '다시 시도',
482            retrying: '다시 시도하는 중…',
483            hint: 'X 앱 안에서 계속 실패하면 오른쪽 위 메뉴에서 Safari 또는 Chrome으로 열어 주세요.',
484            copy: '현재 URL 복사',
485            copied: 'URL을 복사했습니다',
486          },
487        };
488        var startedAt =
489          window.performance && typeof window.performance.now === 'function'
490            ? window.performance.now()
491            : Date.now();
492        var sent = Object.create(null);
493        var timeoutId = null;
494        var monitoring = true;
495        var mainAssetHash = '';
496        var appAssetHash = '';
497
498        function language() {
499          var raw = String(navigator.language || 'en').toLowerCase();
500          if (raw.indexOf('ja') === 0) return 'ja';
501          if (raw.indexOf('ko') === 0) return 'ko';
502          if (raw.indexOf('zh') === 0) {
503            return raw.indexOf('tw') >= 0 || raw.indexOf('hk') >= 0 ? 'zh-TW' : 'zh-CN';
504          }
505          return 'en';
506        }
507
508        function browserFamily() {
509          var ua = String(navigator.userAgent || '');
510          if (/CriOS|Chrome\//i.test(ua)) return 'chrome';
511          if (/FxiOS|Firefox\//i.test(ua)) return 'firefox';
512          if (/EdgiOS|EdgA|Edg\//i.test(ua)) return 'edge';
513          if (/Safari\//i.test(ua) && /AppleWebKit\//i.test(ua)) return 'safari';
514          if (/AppleWebKit\//i.test(ua) && /Mobile\//i.test(ua)) return 'ios_webview';
515          return 'other';
516        }
517
518        function isXInApp() {
519          return /Twitter(?:Android| for iPhone)?|XApp/i.test(String(navigator.userAgent || ''));
520        }
521
522        function elapsedMs() {
523          var now =
524            window.performance && typeof window.performance.now === 'function'
525              ? window.performance.now()
526              : Date.now();
527          return Math.max(0, Math.round(now - startedAt));
528        }
529
530        function assetHash(urlValue) {
531          try {
532            var pathname = new URL(String(urlValue), window.location.href).pathname;
533            var name = pathname.split('/').pop() || '';
534            return name.slice(0, 96);
535          } catch (_error) {
536            return '';
537          }
538        }
539
540        function anonymousId() {
541          try {
542            var existing = window.localStorage.getItem('mychara:anonymousId');
543            if (existing) return existing.slice(0, 64);
544            var fresh =
545              window.crypto && typeof window.crypto.randomUUID === 'function'
546                ? window.crypto.randomUUID()
547                : 'boot-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 10);
548            window.localStorage.setItem('mychara:anonymousId', fresh);
549            return fresh.slice(0, 64);
550          } catch (_error) {
551            return (
552              'boot-' +
553              Date.now().toString(36) +
554              '-' +
555              Math.random().toString(36).slice(2, 10)
556            ).slice(0, 64);
557          }
558        }
559
560        function attribution() {
561          var values = {};
562          try {
563            var params = new URLSearchParams(window.location.search);
564            for (var index = 0; index < ALLOWED_PARAMS.length; index += 1) {
565              var key = ALLOWED_PARAMS[index];
566              var value = params.get(key);
567              if (value) values[key] = value.slice(0, 200);
568            }
569          } catch (_error) {
570            // Malformed query parameters must not block startup.
571          }
572          return values;
573        }
574
575        function safePath() {
576          var query = new URLSearchParams();
577          var values = attribution();
578          for (var index = 0; index < ALLOWED_PARAMS.length; index += 1) {
579            var key = ALLOWED_PARAMS[index];
580            if (values[key]) query.set(key, values[key]);
581          }
582          var suffix = query.toString();
583          return (window.location.pathname + (suffix ? '?' + suffix : '')).slice(0, 300);
584        }
585
586        function send(eventName, extra) {
587          if (sent[eventName]) return;
588          sent[eventName] = true;
589          if (window.location.hostname !== 'mychara.ai') return;
590          var properties = Object.assign({}, attribution(), {
591            measurement_stage: eventName,
592            boot_duration_ms: elapsedMs(),
593            browser_family: browserFamily(),
594            x_in_app: isXInApp(),
595            main_asset_hash: mainAssetHash,
596            app_asset_hash: appAssetHash,
597          });
598          if (extra) Object.assign(properties, extra);
599          var body = JSON.stringify({
600            eventName: eventName,
601            anonymousId: anonymousId(),
602            path: safePath(),
603            properties: properties,
604          });
605          try {
606            if (typeof navigator.sendBeacon === 'function') {
607              var accepted = navigator.sendBeacon(
608                API_URL,
609                new Blob([body], { type: 'application/json' }),
610              );
611              if (accepted) return;
612            }
613            if (typeof window.fetch === 'function') {
614              window
615                .fetch(API_URL, {
616                  method: 'POST',
617                  headers: { 'Content-Type': 'application/json' },
618                  body: body,
619                  keepalive: true,
620                  credentials: 'omit',
621                })
622                .catch(function () {});
623            }
624          } catch (_error) {
625            // Telemetry is never allowed to affect startup.
626          }
627        }
628
629        function shellElements() {
630          var shell = document.querySelector('.app-startup-loading');
631          return {
632            shell: shell,
633            spinner: document.querySelector('.app-startup-loading__spinner'),
634            message: document.querySelector('.app-startup-loading__message'),
635            recovery: document.querySelector('.app-startup-loading__recovery'),
636            retry: document.querySelector('.app-startup-loading__retry'),
637            hint: document.querySelector('.app-startup-loading__external-hint'),
638            copy: document.querySelector('.app-startup-loading__copy'),
639          };
640        }
641
642        function showError() {
643          var elements = shellElements();
644          var text = COPY[language()];
645          if (elements.shell) {
646            elements.shell.setAttribute('role', 'alert');
647            elements.shell.setAttribute('aria-live', 'assertive');
648            elements.shell.setAttribute('aria-busy', 'false');
649          }
650          if (elements.spinner) elements.spinner.hidden = true;
651          if (elements.message) elements.message.textContent = text.failed;
652          if (elements.retry) {
653            elements.retry.textContent = text.retry;
654            elements.retry.href = window.location.href;
655          }
656          if (elements.hint) elements.hint.textContent = text.hint;
657          if (elements.copy) elements.copy.textContent = text.copy;
658          if (elements.recovery) elements.recovery.hidden = false;
659        }
660
661        function cleanupMonitoring() {
662          monitoring = false;
663          if (timeoutId !== null) window.clearTimeout(timeoutId);
664          window.removeEventListener('error', onWindowError, true);
665          window.removeEventListener('unhandledrejection', onUnhandledRejection);
666        }
667
668        function mark(eventName, properties) {
669          var cleanProperties = Object.assign({}, properties || {});
670          if (cleanProperties.main_asset_url) {
671            mainAssetHash = assetHash(cleanProperties.main_asset_url);
672            delete cleanProperties.main_asset_url;
673          }
674          if (cleanProperties.app_asset_url) {
675            appAssetHash = assetHash(cleanProperties.app_asset_url);
676            delete cleanProperties.app_asset_url;
677          }
678          send(eventName, cleanProperties);
679        }
680
681        function complete(properties) {
682          mark('app_boot_completed', properties);
683          cleanupMonitoring();
684        }
685
686        function fail(eventName, properties) {
687          mark(eventName, properties);
688          cleanupMonitoring();
689          showError();
690        }
691
692        function retry(properties) {
693          mark('app_boot_retry', properties);
694          var elements = shellElements();
695          if (elements.retry) elements.retry.textContent = COPY[language()].retrying;
696        }
697
698        function sameOriginScript(filename) {
699          try {
700            return (
701              filename && new URL(filename, window.location.href).origin === window.location.origin
702            );
703          } catch (_error) {
704            return false;
705          }
706        }
707
708        function onWindowError(event) {
709          if (!monitoring) return;
710          var target = event.target;
711          if (target && target.id === 'app-main-module') {
712            fail('app_boot_module_error', { error_kind: 'main_module_resource_error' });
713            return;
714          }
715          if (sameOriginScript(event.filename)) {
716            fail('app_boot_app_module_error', {
717              error_kind: String(event.message || 'module evaluation error').slice(0, 160),
718            });
719          }
720        }
721
722        function onUnhandledRejection(event) {
723          if (!monitoring) return;
724          var reason = event.reason;
725          var message = reason && reason.message ? reason.message : 'unhandled module rejection';
726          fail('app_boot_app_module_error', { error_kind: String(message).slice(0, 160) });
727        }
728
729        window.__MYCHARA_BOOT__ = {
730          mark: mark,
731          complete: complete,
732          fail: fail,
733          retry: retry,
734        };
735
736        window.addEventListener('error', onWindowError, true);
737        window.addEventListener('unhandledrejection', onUnhandledRejection);
738
739        var initialElements = shellElements();
740        if (initialElements.retry) {
741          initialElements.retry.href = window.location.href;
742          initialElements.retry.addEventListener('click', function () {
743            retry({ recovery_surface: 'static_startup' });
744          });
745        }
746        if (initialElements.copy) {
747          initialElements.copy.addEventListener('click', function () {
748            var finish = function () {
749              initialElements.copy.textContent = COPY[language()].copied;
750            };
751            try {
752              if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
753                navigator.clipboard
754                  .writeText(window.location.href)
755                  .then(finish)
756                  .catch(function () {});
757              }
758            } catch (_error) {
759              // Clipboard access is optional recovery help.
760            }
761          });
762        }
763
764        mark('app_boot_html_arrived');
765        timeoutId = window.setTimeout(function () {
766          if (!monitoring) return;
767          fail('app_boot_timeout');
768        }, TIMEOUT_MS);
769      })();
770    </script>
770
771    
771<script>
772      (function () {
773        var moduleScript = document.getElementById('app-main-module');
774        if (moduleScript && window.__MYCHARA_BOOT__) {
775          window.__MYCHARA_BOOT__.mark('app_boot_module_detected', {
776            main_asset_url: moduleScript.src,
777          });
778        }
779      })();
780    </script>
780
781  </body>
782</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.