PageSourceSearch

https://grigsi.com/js/grigsi-help.js?v=6

js grigsi.com collected 2026-10-02 01:31:42 UTC 33,543 bytes, 678 lines download raw bytes

1/**
2 * GriGsi — “G at a glance” chip + modal. Copy is keyed by URL (PAGES).
3 */
4(function () {
5  var global = typeof window !== "undefined" ? window : globalThis;
6  var PREFIX = "G at a glance · ";
7  /** Compact chip glyph: ">" | "?" | "G" */
8  var HELP_CHIP_GLYPH = ">";
9
10  function helpLang() {
11    try {
12      if (global.GriGsiSiteI18n && typeof global.GriGsiSiteI18n.apply === "function") {
13        var ctl = global.GriGsiUiLang && global.localStorage.getItem("grigsi-site-ui-lang");
14        if (ctl === "bg" || ctl === "en") return ctl;
15      }
16      var stored = global.localStorage.getItem("grigsi-site-ui-lang");
17      if (stored === "bg" || stored === "en") return stored;
18    } catch (_) {}
19    var nav = String((global.navigator && global.navigator.language) || "").toLowerCase();
20    return nav.startsWith("bg") ? "bg" : "en";
21  }
22
23  function helpUi() {
24    var lang = helpLang();
25    if (lang === "bg" && global.GriGsiHelpBgDefaults) {
26      return {
27        prefix: "G накратко · ",
28        chipLabel: global.GriGsiHelpBgDefaults.chipLabel || "G накратко",
29        chipAria: global.GriGsiHelpBgDefaults.chipAria || "Помощ",
30        ok: global.GriGsiHelpBgDefaults.ok || "Добре",
31      };
32    }
33    return {
34      prefix: PREFIX,
35      chipLabel: "G at a glance",
36      chipAria: "Help — at a glance for this page",
37      ok: "OK",
38    };
39  }
40
41  function glance(shortTitle, bodyHtml) {
42    return { title: PREFIX + shortTitle, body: bodyHtml };
43  }
44
45  var siteDefault = glance(
46    "GriGsi",
47    "<p><strong>Trust layer</strong> for the open web: community trust signals, <strong>Trust Check</strong> (domains, links, text), and <strong>SENDi!</strong> without classic sign-up.</p>" +
48      "<p>Header: <strong>Tools</strong>, <strong>Solutions</strong>, <strong>Services</strong>, Pricing, About, More (Trust Index and indexes live under More).</p>" +
49      "<p>Built around <strong>hashes and minimal PII</strong>; you control what you share.</p>"
50  );
51
52  var spaceEntryDefault = glance(
53    "SENDi! entry",
54    "<p><strong>SENDi!</strong> is for sending once and continuing only if needed: choose a type, optional password, then create or join with a code or link.</p>" +
55      "<p>A session runs until you leave — not a fixed 24-hour timer.</p>" +
56      "<p>Use the <strong>top menu</strong> for tools, docs, and indexes anytime.</p>"
57  );
58
59  var spaceSpaceDefault = glance(
60    "SENDi!",
61    "<p>You’re inside <strong>SENDi!</strong>: send a photo, file, link, text or voice once — continue if you need to. Chat, files, video, screen sharing, posts, polls, and Trust Check depending on what the host enabled.</p>" +
62      "<p><strong>Background painting:</strong> the chat backdrop is a <strong>public-domain masterpiece</strong> from Wikimedia Commons (one per SENDi! code). Tap <strong>GI</strong> on the caption chip for title, artist, year, and source — in English. GriGsi does not host the image; your browser loads it from the museum/Commons URL.</p>" +
63      "<p>Media is often <strong>peer-to-peer</strong> when the network allows; the server still coordinates signaling and session setup.</p>" +
64      "<p>Leave or close the tab to leave; use the <strong>site menu</strong> for tools elsewhere.</p>"
65  );
66
67  var PAGES = {
68    "/": glance(
69      "Home",
70      "<p><strong>Start here</strong>: quick links to Space, Trust Check, and the main index tools — trust, sources, and learning.</p>" +
71        "<p>The purple bar is the hero; <strong>Index tools</strong> group the main products in one row.</p>" +
72        "<p>Everything is <strong>hash-first</strong>; no account is required for the core flows.</p>"
73    ),
74
75    "/check-index.html": glance(
76      "Trust Check",
77      "<p><strong>Vote</strong> Trust or Warn on a domain, URL, email, phone, IBAN, or text label — only a <strong>hash</strong> of your final label is stored for votes.</p>" +
78        "<p>This combines community votes with verification workflows for the same hash.</p>" +
79        "<p><strong>Open Trust Check</strong> to continue with source-style follow-up for the same text.</p>"
80    ),
81
82    "/trust-index.html": glance(
83      "Trust Index",
84      "<p>Hub for the <strong>trust layer</strong>: how voting works, links to Trust Check, Global Trust guide, Learn Index, and noise tools.</p>" +
85        "<p>Use this page to jump into the right product without mixing up <strong>community votes</strong> vs <strong>claim verification</strong>.</p>" +
86        "<p>Extension users: <strong>Sentinel</strong> (in-page prompt) is explained here — it’s not the same as the trust score alone.</p>"
87    ),
88
89    "/trust-index/global.html": glance(
90      "Global Trust Index (guide)",
91      "<p>Long-form guide: how <strong>Trust / Warn</strong> votes aggregate into a score and <strong>tier</strong> (Observation → Soft → Confirmed, plus Flagged when needed).</p>" +
92        "<p>Describes <strong>hash-first</strong> design, privacy, and how the browser extension fits in.</p>" +
93        "<p><strong>Sentinel</strong> vs <strong>trust score</strong> vs <strong>Trust Check</strong> trusted sources are clarified here.</p>"
94    ),
95
96    "/tools.html": glance(
97      "Tools",
98      "<p><strong>Tool catalog</strong>: verify, protect, collaborate, and understand — Trust Check, indexes, proof, SENDi!, LCI, extension, API.</p>" +
99        "<p>Grouped by job, not by account type. Most flows work <strong>without sign-up</strong>.</p>" +
100        "<p>See <strong>Solutions</strong> for use-case outcomes and <strong>Services</strong> for SENDi! and shares.</p>"
101    ),
102
103    "/solutions.html": glance(
104      "Solutions",
105      "<p><strong>Problem-first map</strong>: verify before action, coordinate privately, read pressure (LCI), govern with signal.</p>" +
106        "<p>Outcome pages — not the full tool list (<strong>Tools</strong>) or delivery layer (<strong>Services</strong>).</p>" +
107        "<p>Start with <strong>Trust Check</strong> when you need to decide now.</p>"
108    ),
109
110    "/services.html": glance(
111      "Services",
112      "<p><strong>Collaboration delivery</strong> on the trust layer: SENDi!, video, governance, community.</p>" +
113        "<p>Explains how people run SENDi! and group flows; media is often <strong>P2P</strong> with server signaling.</p>" +
114        "<p>Pair with <strong>Solutions</strong> for why and <strong>Tools</strong> for the full catalog.</p>"
115    ),
116
117    "/spaces.html": glance(
118      "SENDi! (saved)",
119      "<p>Legacy <strong>/spaces.html</strong> URL — opens <strong>SENDi!</strong> saved sessions on this device.</p>" +
120        "<p>Use <strong>SENDi!</strong> for join, recent, and new sessions.</p>" +
121        "<p>Organisation features: see <strong>Pricing</strong> and <strong>Community</strong>.</p>"
122    ),
123
124    "/privacy.html": glance(
125      "Privacy Policy",
126      "<p>How GriGsi handles <strong>PII</strong>, hashes, telemetry, servers, and third parties — in plain language.</p>" +
127        "<p>Explains what the trust layer stores vs what Spaces and media may involve.</p>" +
128        "<p><strong>Not legal advice</strong> — read the full policy for your jurisdiction.</p>"
129    ),
130
131    "/faq.html": glance(
132      "FAQ",
133      "<p>Short answers on <strong>trust tiers</strong>, Trust Check, SENDi!, voting, and how the hash-based network behaves.</p>" +
134        "<p>Use this when something in the product feels unclear before opening a support thread.</p>" +
135        "<p>Links out to <strong>Privacy</strong> and <strong>Solutions</strong> where deeper detail lives.</p>"
136    ),
137
138    "/developer.html": glance(
139      "API & Developer",
140      "<p><strong>HTTP APIs</strong> for trust checks, Trust Check search/saves, and related endpoints — with headers and limits.</p>" +
141        "<p>Intended for integrators who already understand <strong>hashes and rate limits</strong>.</p>" +
142        "<p>See <strong>Privacy</strong> and <strong>Proof</strong> for how signals are produced.</p>"
143    ),
144
145    "/pricing.html": glance(
146      "Pricing",
147      "<p><strong>Free vs Pro vs Community</strong>: ads, limits, Trust Check saves, Spaces, and device rules.</p>" +
148        "<p>Choose based on whether you need <strong>unlimited</strong> index use or <strong>multi-user</strong> Spaces.</p>" +
149        "<p>Payments unlock <strong>organisation features</strong> — not a personal data profile.</p>"
150    ),
151
152    "/community.html": glance(
153      "Community",
154      "<p>Create a <strong>community</strong> with ads or licence-backed revenue;
154 members can become admins of extensions and Spaces.</p>" +
155        "<p>Describes <strong>open vs closed</strong> communities and rules.</p>" +
156        "<p>Connects to <strong>GriGsi Proof</strong> and governance ideas.</p>"
157    ),
158
159    "/proof.html": glance(
160      "GriGsi Proof",
161      "<p>How the project explains <strong>integrity and transparency</strong> — not a substitute for your own verification.</p>" +
162        "<p>Explains where the system is <strong>hash-first</strong> and where servers still matter.</p>" +
163        "<p>Use alongside <strong>FAQ</strong> and <strong>Privacy</strong>.</p>"
164    ),
165
166    "/how.html": glance(
167      "How it works",
168      "<p>High-level tour of the <strong>trust layer</strong>, Spaces, and tools — for first-time readers.</p>" +
169        "<p>Explains why <strong>no sign-up</strong> is a default and how votes aggregate.</p>" +
170        "<p>Jump to <strong>Trust Check</strong> or <strong>Tools</strong> from the home page when you’re ready.</p>"
171    ),
172
173    "/extension-uninstalled.html": glance(
174      "Extension removed",
175      "<p>You’re here because the <strong>extension</strong> was uninstalled or the browser sent you to this page.</p>" +
176        "<p>You can still use <strong>Trust Check</strong> and Spaces on the web.</p>" +
177        "<p>Reinstall from your browser’s store anytime — the site stays the same.</p>"
178    ),
179
180    "/container-unlock.html": glance(
181      "Container unlock",
182      "<p>Flow for <strong>unlocking</strong> or container-related licence steps — follow the on-page instructions.</p>" +
183        "<p>If something fails, check <strong>Pricing</strong> and your account/device limits.</p>" +
184        "<p>General trust tools stay on <strong>Tools</strong> and <strong>Trust Check</strong>.</p>"
185    ),
186
187    "/survey.html": glance(
188      "Survey",
189      "<p>On-site <strong>survey</strong> — answers help improve flows and wording.</p>" +
190        "<p>Not a substitute for <strong>support</strong> — use Contact on the home page if you need a reply.</p>" +
191        "<p><strong>Privacy Policy</strong> applies to what the server stores.</p>"
192    ),
193
194    "/noise-text-analyzer.html": glance(
195      "Noise (local text)",
196      "<p><strong>Runs in your browser</strong>: measures informational noise in pasted text (speculation, hooks, sourcing gaps).</p>" +
197        "<p>It is <strong>not</strong> the Trust Index score and <strong>not</strong> Trust Check claim verification.</p>" +
198        "<p>For full claim workflows use <strong>Trust Check</strong> after you’ve read the wording here.</p>"
199    ),
200
201    "/learn-index": glance(
202      "Learn Index",
203      "<p><strong>Student practice</strong> first: short safe examples, reflection questions, and a <strong>local noise check</strong> in the browser.</p>" +
204        "<p>Below that: the <strong>practice checklist</strong> and longer EN/BG guides — Trust Check when you’re ready.</p>" +
205        "<p>Designed to complement <strong>not replace</strong> your own judgement.</p>"
206    ),
207
208    "/similarity": glance(
209      "Similarity",
210      "<p><strong>Similarity engine</strong> — compare text or media fingerprints for overlap and relatedness.</p>" +
211        "<p>Useful for spotting duplication or near-duplicates across submissions.</p>" +
212        "<p>Does not replace human review or <strong>Trust Check</strong> sourcing.</p>"
213    ),
214
215    "/similarity/embed.html": glance(
216      "Similarity (embed)",
217      "<p><strong>Embeddable</strong> similarity view for partners or internal pages — same engine as the main tool.</p>" +
218        "<p>Respect <strong>API</strong> and usage limits; see Developer docs.</p>" +
219        "<p><strong>Privacy</strong> applies to what you send in the query.</p>"
220    ),
221
222    "/poll.html": glance(
223      "Polls",
224      "<p>Create and run <strong>polls</strong> — quick counts, hash-friendly client ids, and optional Space context.</p>" +
225        "<p>Not the same as <strong>Trust Check</strong> voting (trust layer) — different purpose.</p>" +
226        "<p>For governance-style surveys see <strong>Public surveys</strong> under Solutions.</p>"
227    ),
228
229    "/SENDi!/": spaceEntryDefault,
230    "/sendi/quick.html": glance(
231      "Quick SENDi!",
232      "<p>Create a <strong>short-lived SENDi!</strong> for the session — chat, files, or media depending on what you open.</p>" +
233        "<p>Ideal for ad-hoc sending <strong>without</strong> a long-lived organisation session.</p>" +
234        "<p>When you’re done, leave; there’s no classic profile tied to you.</p>"
235    ),
236    "/SENDi!/": glance(
237      "Enter (unified)",
238      "<p>Redirects to <strong>SENDi!</strong> — one field for codes and links.</p>" +
239        "<p>If the Space is password-protected, enter the password on the same page.</p>" +
240        "<p>Never share secrets in screenshots you don’t trust.</p>"
241    ),
242    "/instant/": glance(
243      "SENDi!",
244      "<p><strong>SENDi!</strong>: send once — share a link or code; paste a code to join someone else’s session.</p>" +
245        "<p><strong>Find Som</strong> and <strong>My Labels</strong> live in the SENDi! menu.</p>" +
246        "<p>Recent and saved sessions live on this device only.</p>"
247    ),
248    "/instant/?mode=find": glance(
249      "GriGsi Find",
250      "<p><strong>Find</strong> — locate a device without an account. Ring Space (pinned devices) or Quick Find (one-time code).</p>" +
251        "<p>Paste a peer ID in Space chat to add a device. Location stays peer-to-peer.</p>" +
252        "<p>See <strong>docs/GRIGSI-FIND.md</strong> on the repo for architecture.</p>"
253    ),
254    "/sendi/sendi-shell-find.html": glance(
255      "GriGsi Find session",
256      "<p>Minimal find shell — ring, vibrate, compass when GPS is available.</p>" +
257        "<p>Open from SENDi! or <code>?module=find</code> on a SENDi! link.</p>" +
258        "<p>Server stores signaling only — not your coordinates.</p>"
259    ),
260    "/communicator/enter.html": glance(
261      "Enter code or link",
262      "<p>Redirects to <strong>/SENDi!/</strong> — same join field for links and codes.</p>" +
263        "<p>Never share secrets in screenshots you don’t trust.</p>"
264    ),
265    "/SENDi!/": spaceSpaceDefault,
266    "/sendi/waiting.html": glance(
267      "Waiting to join",
268      "<p><strong>Hold</strong> until the host admits you or the Space becomes ready — common for video or gated Spaces.</p>" +
269        "<p>Keep the tab open; if nothing happens, check the code or ask the host.</p>" +
270        "<p>Leaving returns you to normal browsing — no account required.</p>"
271    ),
272    "/sendi/payment-success.html": glance(
273      "Payment success",
274      "<p>Confirms a <strong>completed payment</strong> step for Space or plan upgrades — read the on-page details.</p>" +
275        "<p>If features don’t unlock, refresh after a minute or check <strong>Pricing</strong>.</p>" +
276        "<p>Billing questions belong in your receipt or support channel.</p>"
277    ),
278
279    "/governance/index.html": glance(
280      "Governance",
281      "<p>Overview of <strong>governance</strong> tools: proposals, voting, and shared decision flows.</p>" +
282        "<p>Not the same as <strong>Trust Check</strong> trust votes — read each screen’s purpose.</p>" +
283        "<p>Community admins configure what’s open vs closed.</p>"
284    ),
285    "/governance/create.html": glance(
286      "Create governance",
287      "<p>Start a <strong>governance item</strong> — follow fields for title, options, and timing.</p>" +
288        "<p>Double-check visibility; some ballots are public by link.</p>" +
289        "<p>Abuse reporting may be available via <strong>Community</strong> contacts.</p>"
290    ),
291    "/governance/vote.html": glance(
292      "Public vote",
293      "<p>Cast a <strong>vote</strong> in a governance flow — one client id per device in many modes.</p>" +
294        "<p>Results may aggregate in real time or after close — see the page.</p>" +
295        "<p>This is <strong>not</strong> the Trust Index tier for domains.</p>"
296    ),
297
298    "/admin.html": glance(
299      "Admin",
300      "<p><strong>Operator sign-in</strong> for internal dashboards — use only credentials you were given.</p>" +
301        "<p>All actions should follow your organisation’s policy and local law.</p>" +
302        "<p>Public trust tools remain on the main site for everyone else.</p>"
303    ),
304    "/admin-broadcast.html": glance(
305      "Admin — Live broadcast",
306      "<p><strong>Live broadcast</strong> — extension/apps tab and Space tab for banners and emergency messages.</p>" +
307        "<p>Misuse can affect users; use least privilege.</p>" +
308        "<p>Log out on shared machines.</p>"
309    ),
310    "/admin-live.html": glance(
311      "Admin — Live broadcast",
312      "<p>Redirects to <strong>Live broadcast</strong> (Extension tab).</p>"
313    ),
314    "/admin-signal-warnings.html": glance(
315      "Admin — Signal warnings",
316      "<p>Manage <strong>signal warning</strong> rules and in-browser display config — operator-only, not end-user trust voting.</p>" +
317        "<p>Keep brand safety and regional rules in mind.</p>" +
318        "<p>Separate from <strong>Community</strong> settings in the public product UI.</p>"
319    ),
320    "/org-admin.html": glance(
321      "Org admin",
322      "<p><strong>Organisation</strong> administration: members, Spaces, or domains depending on your licence.</p>" +
323        "<p>Invite and revoke access carefully; hashes don’t replace good access hygiene.</p>" +
324        "<p>See <strong>Pricing</strong> for seat limits.</p>"
325    ),
326    "/admin-trusted-domains.html": glance(
327      "Admin — Trusted domains",
328      "<p>Review or edit <strong>trusted domain</strong> lists used in product flows — incorrect entries change user trust signals.</p>" +
329        "<p>Coordinate with editorial or security before bulk changes.</p>" +
330        "<p>Changes may take time to propagate.</p>"
331    ),
332    "/admin-surveys.html": glance(
333      "Admin — Surveys",
334      "<p>Configure <strong>surveys</strong> and ballots that appear to users — wording matters for consent.</p>" +
335        "<p>Align with <strong>Privacy</strong> for data retention.</p>" +
336        "<p>Test in staging when available.</p>"
337    ),
338    "/admin-stats.html": glance(
339      "Admin — Stats",
340      "<p>Aggregate <strong>statistics</strong> for operations — not personal dossiers; still treat exports as sensitive.</p>" +
341        "<p>Use for capacity and health, not for profiling individuals.</p>" +
342        "<p>Follow your org’s data-handling policy.</p>"
343    ),
344    "/admin-spaces.html": glance(
345      "Admin — Spaces",
346      "<p>Inspect or manage <strong>Space</strong> records for support and abuse response.</p>" +
347        "<p>Prefer self-service tools for users where possible.</p>" +
348        "<p>Escalate legal requests through proper channels.</p>"
349    ),
350    "/admin-signals.html": glance(
351      "Admin — Signals",
352      "<p>Review <strong>signals</strong> feeding trust or safety systems — false positives hurt real users.</p>" +
353        "<p>Correlate with other admin views before acting.</p>" +
354        "<p>Document reasons for overrides.</p>"
355    ),
356    "/admin-licenses.html": glance(
357      "Admin — Licenses",
358      "<p>Manage <strong>licences</strong>, keys, or entitlements — financial and access sensitive.</p>" +
359        "<p>Never post screenshots of keys in public channels.</p>" +
360        "<p>Match records to <strong>Pricing</strong> in the product.</p>"
361    ),
362    "/admin-hashes.html": glance(
363      "Admin — Hashes",
364      "<p>Technical view of <strong>hash</strong> identifiers — used for support and integrity checks.</p>" +
365        "<p>Hashes are not anonymity on their own if combined with other logs.</p>" +
366        "<p>Minimise retention and access.</p>"
367    ),
368    "/admin-extensions.html": glance(
369      "Admin — Extensions",
370      "<p><strong>Extension</strong> rollout and compatibility — store listings vs dev builds.</p>" +
371        "<p>Coordinate releases with browser review times.</p>" +
372        "<p>User-facing help stays on <strong>Tools</strong> and extension stores.</p>"
373    ),
374    "/admin-contact.html": glance(
375      "Admin — Contact",
376      "<p>Inbound <strong>contact</strong> or ticket queues for operators — may contain personal data.</p>" +
377        "<p>Reply from official channels only; watch for phishing.</p>" +
378        "<p>Delete or archive per policy.</p>"
379    ),
380    "/admin-api-licenses.html": glance(
381      "Admin — API licences",
382      "<p><strong>API keys</strong> and partner licences — rotate on suspicion of leak.</p>" +
383        "<p>Rate limits protect everyone; document partner tiers clearly.</p>" +
384        "<p>See <strong>Developer</strong> for public API surface.</p>"
385    ),
386    "/live-check-index.html": glance(
387      "Labour Coverage Index (concept)",
388      "<p><strong>Concept page</strong> for LCI — why a live complement to official stats (spend, time, stress, access).</p>" +
389        "<p><strong>Not</strong> Global Trust Index; open the <strong>LCI dashboard</strong> for the live score, trends, and nominal strips.</p>" +
390        "<p>Methodology evolves — interpret low-sample regions carefully on the dashboard.</p>"
391    ),
392
393    "/air-check.html": glance(
394      "Air Check (demo)",
395      "<p><strong>Live talk → visual context.</strong> Paste what was said; GriGsi searches <strong>free public indexes</strong> (Wikipedia, Wikidata, OpenStreetMap) and returns up to three candidates.</p>" +
396        "<p><strong>Source icons above the quote</strong> toggle Wikipedia, Wikidata, and OSM on or off with one tap — no submenu. If a quote is already pasted, results refresh immediately.</p>" +
397        "<p><strong>Images from the web</strong> are thumbnails or Commons URLs from those sources — GriGsi does not host them; your browser loads them directly from the origin site. <strong>You choose</strong> what goes to air; metaphors and political nicknames often need a human pick.</p>" +
398        "<p><strong>To air</strong> updates the OBS overlay via local sync. Demo tier only — no paid image API or studio mic yet. Pair with <strong>Trust Check</strong> when a claim needs verification, not just a picture.</p>"
399    ),
400
401    "/air-check/overlay.html": glance(
402      "Air Check — OBS overlay",
403      "<p><strong>Producer output only.</strong> This page shows the quote and image the producer approved on <strong>Air Check</strong> — add it as an OBS <strong>Browser Source</strong> (1920×1080).</p>" +
404        "<p><strong>Net images</strong> load from Wikipedia/Wikimedia or other public URLs shown as the source; GriGsi stores only the last payload in <strong>local browser storage</strong> for sync, not on a profile.</p>" +
405        "<p>Check <strong>licensing and context</strong> before broadcast — especially for news and political formats.</p>"
406    ),
407
408    "/open-data-hub/": glance(
409      "Open Data Hub",
410      "<p><strong>Discover</strong> public institutional APIs and datasets GriGsi uses or plans — ECB/Frankfurter, Eurostat, World Bank, commodities.</p>" +
411        "<p><strong>
411Search runs in your browser</strong> — no account, no query text sent for ranking.</p>" +
412        "<p>Phase 1 is <strong>links and documentation</strong>, not live query execution on your behalf.</p>"
413    ),
414
415    "/official-data-hub/": glance(
416      "GriGsi Official Data",
417      "<p><strong>BG fiscal transparency</strong> — ministries, budget COFOG lines, municipalities, procurement portals.</p>" +
418        "<p><strong>Live figures</strong> from Eurostat/NSI and EOP open procurement aggregates; discovery links to МФ, АОП, ЦИК.</p>" +
419        "<p>Signals flag sharp YoY changes or supplier concentration — <strong>not</strong> legal findings. Pair with <a href=\"/check-index.html\">Trust Check</a> for claims.</p>"
420    ),
421
422    "/life-pressure-mirror.html": glance(
423      "How strong is your money?",
424      "<p>Enter what you earn and spend. Press <strong>Calculate</strong>.</p>" +
425        "<p>First you see <strong>how strong your money is</strong>. Then <strong>what's left after bills</strong>.</p>" +
426        "<p>Compare two or more moments to see if things are getting easier or harder.</p>" +
427        "<p>Sources and methods are at the bottom if you want them.</p>"
428    ),
429
430    "/instant/": glance(
431      "SENDi!",
432      "<p><strong>SENDi!</strong>: one tap creates a link and code; share via QR or copy.</p>" +
433        "<p><strong>Join</strong> accepts any GriGsi link or code on one page.</p>" +
434        "<p>One-time codes stop working after first redemption.</p>"
435    ),
436
437    "/about.html": glance(
438      "About",
439      "<p><strong>Mission, context, and contact</strong> — how GriGsi thinks about trust, privacy, and experiments on the open web.</p>" +
440        "<p>Home page <strong>Contact</strong> or links here for partnership, press, or feedback.</p>" +
441        "<p>Deeper detail: <strong>Tools</strong>, <strong>Solutions</strong>, <strong>Services</strong>, <strong>FAQ</strong>.</p>"
442    ),
443
444    "/payment.html": glance(
445      "Payment",
446      "<p>Checkout or upgrade for <strong>Pro</strong>, <strong>Community</strong>, or Space-related plans — follow the on-page steps.</p>" +
447        "<p>Compare limits on <strong>Pricing</strong> before paying.</p>" +
448        "<p>Payments unlock features — not a personal advertising profile.</p>"
449    ),
450  };
451
452  PAGES["/SENDi!/"] = spaceSpaceDefault;
453  PAGES["/SENDi!"] = spaceSpaceDefault;
454  PAGES["/sendi/"] = spaceSpaceDefault;
455  PAGES["/sendi"] = spaceSpaceDefault;
456  PAGES["/governance"] = PAGES["/governance/index.html"];
457  PAGES["/connect"] = spaceSpaceDefault;
458  PAGES["/instant"] = PAGES["/instant/"];
459  PAGES["/privacy"] = PAGES["/privacy.html"];
460
461  function ensureHelpStyles() {
462    if (document.getElementById("grigsi-help-styles-link")) return;
463    var l = document.createElement("link");
464    l.id = "grigsi-help-styles-link";
465    l.rel = "stylesheet";
466    l.href = "/css/grigsi-help.css?v=8";
467    document.head.appendChild(l);
468  }
469
470  /** Collect pathname variants to match static hosts and pretty URLs. */
471  function pathKeys() {
472    var raw = location.pathname || "/";
473    var out = [];
474    function add(x) {
475      if (!x) return;
476      if (out.indexOf(x) === -1) out.push(x);
477    }
478    add(raw);
479    try {
480      add(decodeURIComponent(raw));
481    } catch (_) {}
482    var p = raw;
483    if (p.length > 1 && p.slice(-1) === "/") p = p.slice(0, -1);
484    add(p);
485    if (raw.length > 1 && raw.slice(-1) !== "/") add(raw + "/");
486    if (p.endsWith("/index.html")) {
487      add(p.slice(0, -"/index.html".length) || "/");
488    }
489    if (p === "/index.html") add("/");
490    if (p.endsWith(".html")) add(p.slice(0, -5));
491    return out;
492  }
493
494  function resolvePage() {
495    var lang = helpLang();
496    var bgPages = lang === "bg" && global.GriGsiHelpBgPages ? global.GriGsiHelpBgPages : null;
497    var bgDefaults =
498      lang === "bg" && global.GriGsiHelpBgDefaults ? global.GriGsiHelpBgDefaults : null;
499    var keys = pathKeys();
500    var i;
501    for (i = 0; i < keys.length; i++) {
502      if (bgPages && bgPages[keys[i]]) return bgPages[keys[i]];
503      if (PAGES[keys[i]]) return PAGES[keys[i]];
504    }
505    var p = keys[0] || "";
506    if (p === "/SENDi!/" || p === "/SENDi!" || p === "/sendi/" || p === "/sendi") {
507      return bgDefaults ? bgDefaults.spaceEntry : spaceEntryDefault;
508    }
509    if (p.indexOf("/SENDi!/") === 0 || /SENDi!?/i.test(p) || /^\/se
509ndi/i.test(p)) {
510      return bgDefaults ? bgDefaults.spaceSpace : spaceSpaceDefault;
511    }
512    return bgDefaults ? bgDefaults.site : siteDefault;
513  }
514
515  function applyHelpContent(cfg, ui) {
516    var titleEl = document.getElementById("grigsi-help-dialog-title");
517    var bodyEl = document.getElementById("grigsi-help-dialog-body");
518    var closeBtn = document.querySelector("#grigsi-help-dialog .grigsi-help-close");
519    var label = document.querySelector("#grigsi-help-launch .grigsi-help-label");
520    var btn = document.getElementById("grigsi-help-launch");
521    if (titleEl && cfg) titleEl.innerHTML = cfg.title;
522    if (bodyEl && cfg) bodyEl.innerHTML = cfg.body;
523    if (closeBtn) closeBtn.textContent = ui.ok || "OK";
524    if (label) label.textContent = ui.chipLabel;
525    if (btn) btn.setAttribute("aria-label", ui.chipAria);
526  }
527
528  /** Chip surface is light glass — label/chevron stay black for contrast. */
529  function applyChipTextColors(btn, glyph, label) {
530    var ink = "#000000";
531    [btn, glyph, label].forEach(function (el) {
532      if (!el) return;
533      el.style.setProperty("color", ink, "important");
534      el.style.setProperty("-webkit-text-fill-color", ink, "important");
535    });
536    if (btn) btn.classList.add("grigsi-help-chip--dark-label");
537  }
538
539  function build() {
540    if (document.documentElement.getAttribute("data-grigsi-help") === "off") return;
541    if (document.getElementById("grigsi-help-launch")) return;
542    ensureHelpStyles();
543
544    var cfg = resolvePage();
545    var ui = helpUi();
546
547    var wrap = document.createElement("div");
548    wrap.className = "grigsi-help-wrap grigsi-help-wrap-edge";
549    wrap.setAttribute("aria-hidden", "false");
550
551    var btn = document.createElement("button");
552    btn.type = "button";
553    btn.className = "grigsi-help-chip grigsi-help-chip-compact grigsi-glass-surface";
554    btn.id = "grigsi-help-launch";
555    btn.setAttribute("aria-haspopup", "dialog");
556    btn.setAttribute("aria-controls", "grigsi-help-dialog");
557    btn.setAttribute("aria-label", ui.chipAria);
558    btn.setAttribute("aria-expanded", "false");
559
560    var glyph = document.createElement("span");
561    glyph.className = "grigsi-help-glyph";
562    glyph.setAttribute("aria-hidden", "true");
563    glyph.textContent = HELP_CHIP_GLYPH;
564
565    var label = document.createElement("span");
566    label.className = "grigsi-help-label";
567    label.textContent = ui.chipLabel;
568
569    btn.appendChild(label);
570    btn.appendChild(glyph);
571    applyChipTextColors(btn, glyph, label);
572
573    var dialog = document.createElement("dialog");
574    dialog.id = "grigsi-help-dialog";
575    dialog.className = "grigsi-help-dialog";
576    dialog.setAttribute("aria-labelledby", "grigsi-help-dialog-title");
577
578    dialog.innerHTML =
579      '<div class="grigsi-help-dialog-inner">' +
580      '<h2 id="grigsi-help-dialog-title">' +
581      cfg.title +
582      "</h2>" +
583      '<div id="grigsi-help-dialog-body">' +
584      cfg.body +
585      "</div>" +
586      '<div class="grigsi-help-dialog-actions">' +
587      '<button type="button" class="grigsi-help-close" data-grigsi-help-close>' +
588      ui.ok +
589      "</button>" +
590      "</div></div>";
591
592    wrap.appendChild(btn);
593    document.body.appendChild(wrap);
594    document.body.appendChild(dialog);
595
596    function openDialog() {
597      btn.setAttribute("aria-expanded", "true");
598      try {
599        if (typeof dialog.showModal === "function") {
600          dialog.showModal();
601        } else {
602          dialog.setAttribute("open", "");
603          dialog.style.display = "block";
604        }
605      } catch (_) {
606        dialog.setAttribute("open", "");
607        dialog.style.display = "block";
608      }
609      try {
610        dialog.querySelector(".grigsi-help-close").focus();
611      } catch (_) {}
612    }
613
614    function closeDialog() {
615      btn.setAttribute("aria-expanded", "false");
616      try {
617        if (typeof dialog.close === "function") dialog.close();
618      } catch (_) {}
619      dialog.removeAttribute("open");
620      dialog.style.display = "";
621      try {
622        btn.focus();
623      } catch (_) {}
624    }
625
626    btn.addEventListener("click", function (e) {
627      e.preventDefault();
628      openDialog();
629    });
630
631    dialog.addEventListener("click", function (e) {
632      if (e.target === dialog) closeDialog();
633    });
634
635    dialog.addEventListener("keydown", function (e) {
636      if (e.key === "Escape") {
637        e.preventDefault();
638        closeDialog();
639      }
640    });
641
642    dialog.querySelectorAll("[data-grigsi-help-close]").forEach(function (el) {
643      el.addEventListener("click", closeDialog);
644    });
645
646    global.addEventListener("grigsi-site-lang", function () {
647      var next = resolvePage();
648      var nextUi = helpUi();
649      applyHelpContent(next, nextUi);
650    });
651  }
652
653  if (document.readyState === "loading") {
654    document.addEventListener("DOMContentLoaded", build);
655  } else {
656    build();
657  }
658
659  (function () {
660    var s = document.createElement("script");
661    s.src = "/js/grigsi-guide-loader.js?v=3";
662    s.defer = true;
663    document.head.appendChild(s);
664  })();
665
666  // sendi.js/sendi.html are frozen canon (see .cursor/rules/sendi-canon.mdc), so the SENDi-only
667  // media-analyze add-on can't get a <script> tag added there directly — it loads itself from here
668  // instead, same pathname check resolvePage() above already uses for SENDi's own help content.
669  (function () {
670    var p = "";
671    try { p = global.location.pathname || ""; } catch (_) { return; }
672    if (!(p.indexOf("/SENDi!/") === 0 || /SENDi!?/i.test(p) || /^\/se
672ndi/i.test(p))) return;
673    var s = document.createElement("script");
674    s.src = "/js/sendi-media-analyze.js?v=2";
675    s.defer = true;
676    document.head.appendChild(s);
677  })();
678})();

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.