From 1ed624eaf103eb8fcd56008bd34f697c1bcbe922 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Thu, 2 Jul 2026 01:25:19 +0200 Subject: [PATCH] feat(landing): Russian default + SEO head, icons and OG card MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The landing now always opens in Russian (saved 🌐 choice still wins) — browser-language detection made the indexed content nondeterministic (Googlebot renders with en-US). landing.html gains the static Russian SEO head: title/description, canonical pinned to the production origin, Open Graph card (Telegram/VK link previews), twitter:card, JSON-LD, theme-color and the favicon set; the SPA shell turns noindex and its tab title becomes «Эрудит (Скрэббл)». New assets/icons generator (same tile design as the VK loader) produces favicon.svg/ico, apple-touch-icon.png and og-image.png into ui/public/, plus robots.txt. --- assets/icons/README.md | 41 +++++++++++ assets/icons/build/extract.js | 78 ++++++++++++++++++++ assets/icons/build/generate.js | 128 +++++++++++++++++++++++++++++++++ assets/icons/build/glyphs.json | 1 + docs/ARCHITECTURE.md | 9 ++- docs/FUNCTIONAL.md | 8 ++- docs/FUNCTIONAL_ru.md | 9 ++- ui/e2e/landing.spec.ts | 29 +++++--- ui/index.html | 12 +++- ui/landing.html | 45 +++++++++++- ui/public/apple-touch-icon.png | Bin 0 -> 6405 bytes ui/public/favicon.ico | Bin 0 -> 1237 bytes ui/public/favicon.svg | 1 + ui/public/og-image.png | Bin 0 -> 43130 bytes ui/public/robots.txt | 2 + ui/src/Landing.svelte | 13 +++- ui/src/landing.ts | 9 +++ 17 files changed, 367 insertions(+), 18 deletions(-) create mode 100644 assets/icons/README.md create mode 100644 assets/icons/build/extract.js create mode 100644 assets/icons/build/generate.js create mode 100644 assets/icons/build/glyphs.json create mode 100644 ui/public/apple-touch-icon.png create mode 100644 ui/public/favicon.ico create mode 100644 ui/public/favicon.svg create mode 100644 ui/public/og-image.png create mode 100644 ui/public/robots.txt diff --git a/assets/icons/README.md b/assets/icons/README.md new file mode 100644 index 0000000..3b8cde5 --- /dev/null +++ b/assets/icons/README.md @@ -0,0 +1,41 @@ +# Erudit — site icons + Open Graph card + +The favicon set and the `og:image` link-preview card for the public landing +(`ui/landing.html`) and the SPA shell (`ui/index.html`). Same design language as the +[VK loading-screen logo](../vk/README.md): the wooden Erudit «Э» tile (score `8`), +with the wordmark on the app's dark board green (`ui/src/app.css` tokens). + +| Output (committed to `ui/public/`) | Purpose | +|------|---------| +| `favicon.svg` | Vector favicon, transparent; tile + «Э» only (the score is illegible below ~32 px). | +| `favicon.ico` | 32×32 PNG-in-ICO fallback (also answers the browsers' blind `/favicon.ico` probe). | +| `apple-touch-icon.png` | 180×180 opaque full-bleed tile; iOS masks its own corners. | +| `og-image.png` | 1200×630 card: tile + «Эрудит / Скрэббл — игра в слова». Referenced absolutely as `https://erudit-game.ru/og-image.png`. | + +## How it works + +`build/extract.js` extracts the needed glyph outlines (tile glyphs + every wordmark +character) from LiberationSans (Arial-metric, the game's font stack) with their +advance widths into `build/glyphs.json` (committed). `build/generate.js` composes +plain SVG from those outlines — no font is needed at generation time — writes +`favicon.svg` and rasterises the PNG/ICO outputs by screenshotting the SVGs with the +`ui` package's Playwright chromium (`@playwright/test`); the `.ico` container is +assembled in-script (a single PNG entry). Raster bytes therefore depend on the +installed chromium version; the SVG sources are deterministic. + +## Regenerate + +Requirements: Node ≥ 18, `ui` installed (`pnpm install`, provides Playwright). +`extract.js` additionally needs `opentype.js` (`npm i opentype.js`); **`generate.js` +needs no extra packages**. + +```sh +cd assets/icons + +# 1. (optional) re-extract the glyphs — only if the font or the wordmark changes: +# default font: /usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf +node build/extract.js [/path/to/font.ttf] # -> build/glyphs.json + +# 2. regenerate everything in ui/public/: +node build/generate.js +``` diff --git a/assets/icons/build/extract.js b/assets/icons/build/extract.js new file mode 100644 index 0000000..0df2800 --- /dev/null +++ b/assets/icons/build/extract.js @@ -0,0 +1,78 @@ +'use strict'; +// Extract the glyph outlines the site icons and the og-image wordmark need from a +// grotesque font (LiberationSans = Arial-metric, matching the game's system-ui/Arial +// stack) and emit cubic-bezier contours per character, baseline at y=0, y-down, +// plus the advance width so generate.js can lay out words without the font. +// Same outline conversion as ../../vk/build/extract.js, generalised to a char set. +const opentype = require('opentype.js'); +const fs = require('fs'); + +const FONT = process.argv[2] || '/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf'; +const b = fs.readFileSync(FONT); +const font = opentype.parse(b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength)); +const FS = 1000; // em scale + +// The tile glyphs («Э», «8») + every character of the og-image wordmark lines +// («Эрудит», «Скрэббл — игра в слова»). The space carries only an advance. +const CHARS = [...new Set('Э8рудитСкэббл—игра в слова')]; + +function glyphData(ch) { + const g = font.charToGlyph(ch); + const p = g.getPath(0, 0, FS); // baseline at y=0, y-down + const contours = []; + let cur = null, prev = null; + for (const c of p.commands) { + if (c.type === 'M') { + if (cur) contours.push(cur); + cur = [{ v: [c.x, c.y], i: [c.x, c.y], o: [c.x, c.y] }]; + prev = { x: c.x, y: c.y }; + } else if (c.type === 'L') { + cur.push({ v: [c.x, c.y], i: [c.x, c.y], o: [c.x, c.y] }); + prev = { x: c.x, y: c.y }; + } else if (c.type === 'C') { + cur[cur.length - 1].o = [c.x1, c.y1]; + cur.push({ v: [c.x, c.y], i: [c.x2, c.y2], o: [c.x, c.y] }); + prev = { x: c.x, y: c.y }; + } else if (c.type === 'Q') { + const c1 = [prev.x + 2 / 3 * (c.x1 - prev.x), prev.y + 2 / 3 * (c.y1 - prev.y)]; + const c2 = [c.x + 2 / 3 * (c.x1 - c.x), c.y + 2 / 3 * (c.y1 - c.y)]; + cur[cur.length - 1].o = c1; + cur.push({ v: [c.x, c.y], i: c2, o: [c.x, c.y] }); + prev = { x: c.x, y: c.y }; + } else if (c.type === 'Z') { + if (cur && cur.length > 1) { + const last = cur[cur.length - 1], first = cur[0]; + if (Math.hypot(last.v[0] - first.v[0], last.v[1] - first.v[1]) < 1e-3) { + first.i = last.i; // fold the duplicate closing point into the first + cur.pop(); + } + } + if (cur) { contours.push(cur); cur = null; } + } + } + if (cur) contours.push(cur); + + let minx = Infinity, miny = Infinity, maxx = -Infinity, maxy = -Infinity; + const out = contours.map(ct => { + const v = [], i = [], o = []; + ct.forEach(pt => { + v.push(pt.v); + i.push([pt.i[0] - pt.v[0], pt.i[1] - pt.v[1]]); + o.push([pt.o[0] - pt.v[0], pt.o[1] - pt.v[1]]); + minx = Math.min(minx, pt.v[0]); maxx = Math.max(maxx, pt.v[0]); + miny = Math.min(miny, pt.v[1]); maxy = Math.max(maxy, pt.v[1]); + }); + return { i, o, v, c: true }; + }); + const bbox = out.length + ? { x: minx, y: miny, w: maxx - minx, h: maxy - miny } + : { x: 0, y: 0, w: 0, h: 0 }; // the space has no outline + return { adv: g.advanceWidth * (FS / font.unitsPerEm), bbox, contours: out }; +} + +const glyphs = {}; +for (const ch of CHARS) glyphs[ch] = glyphData(ch); + +const out = __dirname + '/glyphs.json'; +fs.writeFileSync(out, JSON.stringify({ em: FS, glyphs })); +console.log('wrote', out, fs.statSync(out).size, 'bytes;', CHARS.length, 'glyphs:', CHARS.join('')); diff --git a/assets/icons/build/generate.js b/assets/icons/build/generate.js new file mode 100644 index 0000000..4ac9928 --- /dev/null +++ b/assets/icons/build/generate.js @@ -0,0 +1,128 @@ +'use strict'; +// Site icons + the Open Graph card for the public landing, drawn from the same +// design as ../../vk (the wooden Erudit tile: face «Э», score «8») and the app's +// board palette (ui/src/app.css). Everything is composed as SVG from the committed +// glyph outlines (build/extract.js -> glyphs.json), so no font is needed at build +// time; the PNG/ICO rasters are screenshots taken with the ui package's Playwright +// chromium (@playwright/test re-exports the browser API). Outputs go straight to +// ui/public/: +// favicon.svg 96 viewBox, transparent, tile + «Э» (the score is illegible small) +// favicon.ico 32x32 PNG-in-ICO render of the same +// apple-touch-icon.png 180x180 opaque full-bleed tile (iOS masks its own corners) +// og-image.png 1200x630 card: tile + wordmark on the board green +const fs = require('fs'); +const path = require('path'); + +const G = JSON.parse(fs.readFileSync(path.join(__dirname, 'glyphs.json'), 'utf8')); +const UI = path.resolve(__dirname, '../../../ui'); +const OUT = path.join(UI, 'public'); + +// ---- palette (vk loader tile + app.css board tokens) ------------------------ +const FACE = '#D9B978', BORDER = '#B49559', GLYPH = '#1A1A1A'; +const BOARD_DARK = '#2a3330', TEXT = '#e7ece8', TEXT_MUTED = '#cdd6cf'; + +// ---- glyph outlines -> SVG path data ---------------------------------------- +const r2 = n => Math.round(n * 100) / 100; +// pathD renders one glyph's contours scaled by sc and translated by (tx, ty). +function pathD(g, sc, tx, ty) { + const pt = (v, d) => `${r2(v[0] * sc + tx + d[0] * sc)} ${r2(v[1] * sc + ty + d[1] * sc)}`; + const Z = [0, 0]; + return g.contours.map(ct => { + const n = ct.v.length; + let d = `M${pt(ct.v[0], Z)}`; + for (let k = 1; k <= n; k++) { + const a = k - 1, b = k % n; + d += `C${pt(ct.v[a], ct.o[a])} ${pt(ct.v[b], ct.i[b])} ${pt(ct.v[b], Z)}`; + } + return d + 'Z'; + }).join(''); +} +// glyphAt centres a glyph's bbox at (cx, cy) with the given pixel cap height, the +// same placement rule as the vk loader's glyph(). stroke fattens it slightly. +function glyphAt(ch, capPx, cx, cy, stroke, colour) { + const g = G.glyphs[ch], sc = capPx / g.bbox.h; + const d = pathD(g, sc, cx - (g.bbox.x + g.bbox.w / 2) * sc, cy - (g.bbox.y + g.bbox.h / 2) * sc); + return ``; +} +// textLine lays out a string on a baseline from the per-glyph advances; capPx sets +// the capital height (measured on «Э»). Returns the combined path + the width. +function textLine(str, capPx, x, y, colour) { + const sc = capPx / G.glyphs['Э'].bbox.h; + let d = '', w = 0; + for (const ch of str) { + const g = G.glyphs[ch]; + if (g.contours.length) d += pathD(g, sc, x + w, y); + w += g.adv * sc; + } + return { svg: ``, width: w }; +} +// tile draws the rounded wooden tile centred at (cx, cy): size px wide/high, with +// the vk loader's corner (6/52) and rim proportions, «Э» and optionally the «8». +function tile(cx, cy, size, withScore) { + const h = size / 2, rx = size * (6 / 52), rim = size * (1.8 / 52); + let s = ``; + s += glyphAt('Э', size * (32 / 52), cx, cy - size * (1 / 52), size * (1 / 52), GLYPH); + if (withScore) s += glyphAt('8', size * (8.5 / 52), cx + size * (19.5 / 52), cy + size * (18.5 / 52), size * (0.5 / 52), GLYPH); + return s; +} +const svg = (w, h, body) => `${body}`; + +// ---- favicon.svg (the committed vector master) ------------------------------- +const favicon = svg(96, 96, tile(48, 48, 88, false)) + '\n'; + +// ---- apple-touch-icon: opaque full bleed, iOS applies its own corner mask ---- +const appleTouch = svg(180, 180, + `` + + `` + + glyphAt('Э', 100, 90, 88, 3, GLYPH) + + glyphAt('8', 26, 146, 142, 1.5, GLYPH)); + +// ---- og-image: tile + wordmark, centred as one group on the board green ------ +function ogImage() { + const W = 1200, H = 630, tileSize = 340, gap = 84; + const l1 = textLine('Эрудит', 112, 0, 0, TEXT); + const l2 = textLine('Скрэббл — игра в слова', 44, 0, 0, TEXT_MUTED); + const textW = Math.max(l1.width, l2.width); + const left = (W - (tileSize + gap + textW)) / 2; + const tx = left + tileSize + gap; + // Two baselines around the vertical centre; the tile centre sits between them. + const b1 = 295, b2 = 408; + const body = + `` + + tile(left + tileSize / 2, H / 2, tileSize, true) + + textLine('Эрудит', 112, tx, b1, TEXT).svg + + textLine('Скрэббл — игра в слова', 44, tx, b2, TEXT_MUTED).svg; + console.log(`og-image: text ${Math.round(textW)}px wide, group left ${Math.round(left)}px`); + return svg(W, H, body); +} + +// ---- rasterisation (Playwright chromium from ui/node_modules) ---------------- +async function shoot(page, markup, w, h, transparent) { + await page.setViewportSize({ width: w, height: h }); + await page.setContent(`${markup}`); + return page.screenshot({ omitBackground: transparent }); +} +// icoFromPNG wraps one PNG as a single-entry .ico (ICONDIR + ICONDIRENTRY + PNG). +function icoFromPNG(png, sizePx) { + const h = Buffer.alloc(22); + h.writeUInt16LE(0, 0); h.writeUInt16LE(1, 2); h.writeUInt16LE(1, 4); // icon, 1 image + h.writeUInt8(sizePx, 6); h.writeUInt8(sizePx, 7); // 32x32 + h.writeUInt16LE(1, 10); h.writeUInt16LE(32, 12); // planes, 32bpp + h.writeUInt32LE(png.length, 14); h.writeUInt32LE(22, 18); // size, offset + return Buffer.concat([h, png]); +} + +(async () => { + fs.writeFileSync(path.join(OUT, 'favicon.svg'), favicon); + const { chromium } = require(path.join(UI, 'node_modules', '@playwright/test')); + const browser = await chromium.launch(); + const page = await browser.newPage(); + const fav32 = await shoot(page, svg(32, 32, tile(16, 16, 29.33, false)), 32, 32, true); + fs.writeFileSync(path.join(OUT, 'favicon.ico'), icoFromPNG(fav32, 32)); + fs.writeFileSync(path.join(OUT, 'apple-touch-icon.png'), await shoot(page, appleTouch, 180, 180, false)); + fs.writeFileSync(path.join(OUT, 'og-image.png'), await shoot(page, ogImage(), 1200, 630, false)); + await browser.close(); + for (const f of ['favicon.svg', 'favicon.ico', 'apple-touch-icon.png', 'og-image.png']) { + console.log('wrote', path.join(OUT, f), fs.statSync(path.join(OUT, f)).size, 'bytes'); + } +})(); diff --git a/assets/icons/build/glyphs.json b/assets/icons/build/glyphs.json new file mode 100644 index 0000000..a3baa7a --- /dev/null +++ b/assets/icons/build/glyphs.json @@ -0,0 +1 @@ +{"em":1000,"glyphs":{"8":{"adv":556.15234375,"bbox":{"x":43.45703125,"y":-698.2421875,"w":469.23828125,"h":708.0078125},"contours":[{"i":[[0,-45.247395833333314],[0,0],[40.364583333333314,-35.48177083333333],[75.52083333333331,0],[0,0],[41.50390625,34.830729166666664],[0,64.12760416666666],[0,0],[-25.71614583333333,30.598958333333314],[-40.0390625,6.510416666666686],[0,0],[0,0],[21.647135416666657,29.296875],[0,39.388020833333314],[0,0],[-39.22526041666666,32.55208333333337],[-66.08072916666666,0],[0,0],[-39.225260416666686,-31.90104166666663],[0,-54.36197916666663],[0,0],[21.809895833333314,-29.296875],[37.760416666666686,-7.486979166666686],[0,0],[0,0],[-24.4140625,-30.110677083333314]],"o":[[0,0],[0,63.4765625],[-40.364583333333314,35.48177083333333],[0,0],[-73.56770833333331,0],[-41.50390625,-34.83072916666666],[0,0],[0,-44.921875],[25.71614583333333,-30.598958333333314],[0,0],[0,0],[-37.434895833333314,-8.7890625],[-21.647135416666657,-29.296875],[0,0],[0,-52.40885416666663],[39.22526041666666,-32.55208333333337],[0,0],[67.70833333333331,0],[39.225260416666686,31.90104166666663],[0,0],[0,39.388020833333314],[-21.809895833333314,29.296875],[0,0],[0,0],[43.9453125,7.161458333333314],[24.4140625,30.110677083333314]],"v":[[512.6953125,-191.89453125],[512.6953125,-191.89453125],[452.1484375,-43.45703125],[278.3203125,9.765625],[278.3203125,9.765625],[105.712890625,-42.48046875],[43.45703125,-190.91796875],[43.45703125,-190.91796875],[82.03125,-304.19921875],[180.6640625,-359.86328125],[180.6640625,-359.86328125],[180.6640625,-361.81640625],[92.041015625,-418.9453125],[59.5703125,-521.97265625],[59.5703125,-521.97265625],[118.408203125,-649.4140625],[276.3671875,-698.2421875],[276.3671875,-698.2421875],[436.767578125,-650.390625],[495.60546875,-520.99609375],[495.60546875,-520.99609375],[462.890625,-417.96875],[373.53515625,-362.79296875],[373.53515625,-362.79296875],[373.53515625,-360.83984375],[476.07421875,-304.931640625]],"c":true},{"i":[[0,42.643229166666686],[0,0],[85.28645833333331,0],[0,0],[21.647135416666657,-19.53125],[0,-38.73697916666663],[0,0],[-22.298177083333343,-20.670572916666686],[-40.69010416666666,0],[0,0],[-21.647135416666686,19.04296875]],"o":[[0,0],[0,-77.79947916666663],[0,0],[-41.341145833333314,0],[-21.647135416666657,19.53125],[0,0],[0,39.388020833333314],[22.298177083333343,20.670572916666686],[0,0],[41.341145833333314,0],[21.647135416666686,-19.04296875]],"v":[[404.296875,-516.11328125],[404.296875,-516.11328125],[276.3671875,-632.8125],[276.3671875,-632.8125],[181.884765625,-603.515625],[149.4140625,-516.11328125],[149.4140625,-516.11328125],[182.861328125,-426.025390625],[277.34375,-395.01953125],[277.34375,-395.01953125],[371.826171875,-423.583984375]],"c":true},{"i":[[0,50.130208333333314],[0,0],[25.390625,21.647135416666686],[45.8984375,0],[0,0],[25.065104166666657,-23.274739583333314],[0,-40.69010416666666],[0,0],[-96.6796875,0],[0,0],[-23.4375,22.94921875]],"o":[[0,0],[0,-42.64322916666666],[-25.390625,-21.647135416666686],[0,0],[-44.59635416666666,0],[-25.065104166666657,23.274739583333314],[0,0],[0,94.7265625],[0,0],[47.8515625,0],[23.4375,-22.94921875]],"v":[[421.38671875,-200.1953125],[421.38671875,-200.1953125],[383.30078125,-296.630859375],[276.3671875,-329.1015625],[276.3671875,-329.1015625],[171.875,-294.189453125],[134.27734375,-198.2421875],[134.27734375,-198.2421875],[279.296875,-56.15234375],[279.296875,-56.15234375],[386.23046875,-90.576171875]],"c":true}]},"Э":{"adv":718.75,"bbox":{"x":51.26953125,"y":-698.2421875,"w":632.8125,"h":708.0078125},"contours":[{"i":[[69.3359375,0],[0,0],[35.481770833333314,-21.97265625],[14.6484375,-38.41145833333337],[0,0],[0,0],[-49.15364583333333,28.64583333333337],[-73.2421875,0],[0,0],[-59.24479166666663,-62.17447916666663],[0,-109.70052083333331],[0,0],[26.3671875,-53.7109375],[50.29296875,-28.971354166666664],[69.98697916666663,0],[0,0],[59.89583333333333,121.09375],[0,0],[0,0],[-37.434895833333314,-24.90234375],[-47.200520833333314,0],[0,0],[-43.45703125,44.10807291666666],[-6.184895833333371,74.86979166666666],[0,0],[0,0],[0,0],[0,0],[41.82942708333337,41.17838541666663]],"o":[[0,0],[-49.479166666666686,0],[-35.481770833333314,21.97265625],[0,0],[0,0],[23.111979166666657,-56.31510416666663],[49.153645833333314,-28.64583333333337],[0,0],[104.81770833333331,0],[59.24479166666663,62.17447916666663],[0,0],[0,72.59114583333331],[-26.3671875,53.7109375],[-50.29296875,28.971354166666664],[0,0],[-138.671875,0],[0,0],[0,0],[22.4609375,45.57291666666666],[37.434895833333314,24.90234375],[0,0],[69.3359375,0],[43.45703125,-44.10807291666666],[0,0],[0,0],[0,0],[0,0],[-6.8359375,-74.54427083333331],[-41.829427083333314,-41.17838541666663]],"v":[[348.14453125,-622.0703125],[348.14453125,-622.0703125],[220.703125,-589.111328125],[145.5078125,-498.53515625],[145.5078125,-498.53515625],[57.12890625,-527.83203125],[165.52734375,-655.2734375],[349.12109375,-698.2421875],[349.12109375,-698.2421875],[595.21484375,-604.98046875],[684.08203125,-347.16796875],[684.08203125,-347.16796875],[644.53125,-157.71484375],[529.541015625,-33.69140625],[349.12109375,9.765625],[349.12109375,9.765625],[51.26953125,-171.875],[51.26953125,-171.875],[127.44140625,-209.9609375],[217.28515625,-104.248046875],[344.23828125,-66.89453125],[344.23828125,-66.89453125],[513.427734375,-133.056640625],[587.890625,-311.5234375],[587.890625,-311.5234375],[268.5546875,-311.5234375],[268.5546875,-386.71875],[587.890625,-386.71875],[514.892578125,-560.302734375]],"c":true}]},"р":{"adv":556.15234375,"bbox":{"x":64.453125,"y":-537.59765625,"w":449.70703125,"h":745.1171875},"contours":[{"i":[[0,-93.42447916666663],[0,0],[129.55729166666663,0],[0,0],[27.994791666666657,61.197916666666664],[0,0],[0,0],[0,-52.734375],[0,0],[0,0],[0,0],[0,0],[1.953125,17.578125],[0,0],[0,0],[-0.6510416666666572,-7.975260416666629],[-0.8138020833333428,-16.6015625],[0,-6.184895833333314],[0,0],[0,0],[-25.716145833333343,15.13671875],[-41.9921875,0],[0,0],[-32.2265625,-43.61979166666663]],"o":[[0,0],[0,184.24479166666666],[0,0],[-81.38020833333331,0],[0,0],[0,0],[1.3020833333333428,2.6041666666666714],[0,0],[0,0],[0,0],[0,0],[0,-54.361979166666686],[0,0],[0,0],[0.3255208333333428,1.3020833333333712],[0.6510416666666572,7.975260416666686],[0.8138020833333428,16.6015625],[0,0],[0,0],[15.625,-32.552083333333314],[25.716145833333343,-15.13671875],[0,0],[65.10416666666663,0],[32.2265625,43.619791666666686]],"v":[[514.16015625,-266.6015625],[514.16015625,-266.6015625],[319.82421875,9.765625],[319.82421875,9.765625],[155.76171875,-82.03125],[155.76171875,-82.03125],[153.3203125,-82.03125],[155.2734375,0.9765625],[155.2734375,0.9765625],[155.2734375,207.51953125],[67.3828125,207.51953125],[67.3828125,-420.41015625],[64.453125,-528.3203125],[64.453125,-528.3203125],[149.4140625,-528.3203125],[150.87890625,-514.404296875],[153.076171875,-477.5390625],[154.296875,-443.359375],[154.296875,-443.359375],[156.25,-443.359375],[218.26171875,-514.892578125],[319.82421875,-537.59765625],[319.82421875,-537.59765625],[465.8203125,-472.16796875]],"c":true},{"i":[[0,75.52083333333331],[0,0],[19.856770833333314,31.575520833333314],[43.294270833333314,0],[0,0],[19.694010416666657,-14.6484375],[10.25390625,-31.087239583333314],[0,-49.8046875],[0,0],[-22.135416666666657,-32.87760416666666],[-49.8046875,0],[0,0],[-20.01953125,32.06380208333333]],"o":[[0,0],[0,-73.56770833333331],[-19.856770833333314,-31.575520833333314],[0,0],[-34.830729166666686,0],[-19.694010416666657,14.6484375],[-10.25390625,31.087239583333314],[0,0],[0,69.3359375],[22.135416666666657,32.87760416666666],[0,0],[43.619791666666686,0],[20.01953125,-32.063802083333314]],"v":[[421.875,-264.6484375],[421.875,-264.6484375],[392.08984375,-422.36328125],[297.36328125,-469.7265625],[297.36328125,-469.7265625],[215.576171875,-447.75390625],[170.654296875,-379.150390625],[155.2734375,-257.8125],[155.2734375,-257.8125],[188.4765625,-104.4921875],[296.38671875,-55.17578125],[296.38671875,-55.17578125],[391.845703125,-103.271484375]],"c":true}]},"у":{"adv":500,"bbox":{"x":2.44140625,"y":-528.3203125,"w":495.60546875,"h":735.83984375},"contours":[{"i":[[28.971354166666657,0],[0,0],[16.276041666666664,3.580729166666657],[0,0],[0,0],[-14.973958333333329,0],[0,0],[-31.901041666666657,80.40364583333333],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.278645833333343,-6.34765625],[-12.369791666666657,-36.1328125],[-0.9765625,-4.231770833333329],[0,0],[0,0],[0,0],[0,0],[0,0],[18.880208333333343,-27.506510416666657],[22.94921875,-13.509114583333343]],"o":[[0,0],[-24.088541666666657,0],[0,0],[0,0],[12.369791666666664,1.953125],[0,0],[54.6875,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.6276041666666572,4.557291666666657],[2.278645833333343,6.34765625],[12.369791666666657,36.1328125],[0,0],[0,0],[0,0],[0,0],[0,0],[-21.809895833333314,56.315104166666664],[-18.880208333333343,27.506510416666657],[-22.94921875,13.509114583333343]],"v":[[93.26171875,207.51953125],[93.26171875,207.51953125],[32.71484375,202.1484375],[32.71484375,202.1484375],[32.71484375,136.23046875],[73.73046875,139.16015625],[73.73046875,139.16015625],[203.61328125,18.5546875],[203.61328125,18.5546875],[211.9140625,-2.44140625],[2.44140625,-528.3203125],[96.19140625,-528.3203125],[207.51953125,-236.328125],[213.37890625,-219.970703125],[235.3515625,-156.25],[255.37109375,-95.703125],[255.37109375,-95.703125],[289.55078125,-191.89453125],[405.2734375,-528.3203125],[498.046875,-528.3203125],[294.921875,0],[233.88671875,125.732421875],[171.142578125,187.255859375]],"c":true}]},"д":{"adv":583.49609375,"bbox":{"x":9.765625,"y":-528.3203125,"w":556.640625,"h":727.5390625},"contours":[{"i":[[0,0],[0,0],[0,0],[14.6484375,-65.59244791666663],[20.833333333333343,-47.20052083333333],[0,0]],"o":[[0,0],[0,0],[-12.044270833333343,88.54166666666663],[-14.6484375,65.59244791666666],[0,0],[0,0]],"v":[[407.2265625,-63.96484375],[407.2265625,-464.35546875],[257.8125,-464.35546875],[217.7734375,-233.154296875],[164.55078125,-63.96484375],[164.55078125,-63.96484375]],"c":true},{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-17.90364583333333,74.86979166666666],[-14.973958333333343,119.140625],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[24.4140625,-40.69010416666666],[17.903645833333343,-74.86979166666663],[0,0],[0,0],[0,0],[0,0]],"v":[[566.40625,-63.96484375],[566.40625,199.21875],[486.81640625,199.21875],[486.81640625,0],[89.35546875,0],[89.35546875,199.21875],[9.765625,199.21875],[9.765625,-63.96484375],[67.87109375,-63.96484375],[131.34765625,-237.3046875],[180.6640625,-528.3203125],[180.6640625,-528.3203125],[495.1171875,-528.3203125],[495.1171875,-63.96484375]],"c":true}]},"и":{"adv":558.59375,"bbox":{"x":69.3359375,"y":-528.3203125,"w":419.921875,"h":528.3203125},"contours":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.1393229166666856,23.763020833333314],[-0.9765625,10.091145833333314],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-11.71875],[1.1393229166666856,-23.763020833333314],[0,0],[0,0],[0,0],[0,0]],"v":[[69.3359375,-528.3203125],[154.296875,-528.3203125],[154.296875,-239.2578125],[149.4140625,-104.00390625],[393.06640625,-528.3203125],[489.2578125,-528.3203125],[489.2578125,0],[405.2734375,0],[405.2734375,-322.265625],[406.982421875,-375.48828125],[410.15625,-426.26953125],[410.15625,-426.26953125],[163.0859375,0],[69.3359375,0]],"c":true}]},"т":{"adv":458.0078125,"bbox":{"x":17.08984375,"y":-528.3203125,"w":423.828125,"h":528.3203125},"contours":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[17.08984375,-464.35546875],[17.08984375,-528.3203125],[440.91796875,-528.3203125],[440.91796875,-464.35546875],[272.94921875,-464.35546875],[272.94921875,0],[185.05859375,0],[185.05859375,-464.35546875]],"c":true}]},"С":{"adv":722.16796875,"bbox":{"x":50.78125,"y":-698.2421875,"w":633.30078125,"h":708.0078125},"contours":[{"i":[[48.502604166666686,0],[0,0],[42.317708333333314,-48.99088541666663],[0,-85.28645833333331],[0,0],[-44.10807291666666,-51.26953125],[-75.1953125,0],[0,0],[-48.50260416666663,95.37760416666666],[0,0],[0,0],[51.26953125,-30.924479166666657],[67.70833333333331,0],[0,0],[50.618489583333314,28.80859375],[26.529947916666657,53.54817708333333],[0,73.2421875],[0,0],[-59.24479166666666,62.17447916666663],[-104.81770833333331,0],[0,0],[-49.15364583333337,-28.64583333333337],[-23.11197916666663,-56.31510416666663],[0,0],[0,0],[35.31901041666663,21.15885416666663]],"o":[[0,0],[-76.171875,0],[-42.317708333333314,48.990885416666686],[0,0],[0,84.30989583333331],[44.10807291666666,51.26953125],[0,0],[96.35416666666663,0],[0,0],[0,0],[-28.3203125,59.24479166666666],[-51.26953125,30.924479166666664],[0,0],[-69.3359375,0],[-50.618489583333314,-28.80859375],[-26.529947916666657,-53.548177083333314],[0,0],[0,-109.70052083333331],[59.24479166666666,-62.17447916666663],[0,0],[73.2421875,0],[49.15364583333337,28.64583333333337],[0,0],[0,0],[-15.950520833333371,-40.0390625],[-35.319010416666686,-21.15885416666663]],"v":[[386.71875,-622.0703125],[386.71875,-622.0703125],[208.984375,-548.583984375],[145.5078125,-347.16796875],[145.5078125,-347.16796875],[211.669921875,-143.798828125],[390.625,-66.89453125],[390.625,-66.89453125],[607.91015625,-209.9609375],[607.91015625,-209.9609375],[684.08203125,-171.875],[564.697265625,-36.62109375],[386.23046875,9.765625],[386.23046875,9.765625],[206.298828125,-33.447265625],[90.576171875,-156.982421875],[50.78125,-347.16796875],[50.78125,-347.16796875],[139.6484375,-604.98046875],[385.7421875,-698.2421875],[385.7421875,-698.2421875],[569.3359375,-655.2734375],[677.734375,-527.83203125],[677.734375,-527.83203125],[589.35546875,-498.53515625],[512.451171875,-590.33203125]],"c":true}]},"к":{"adv":437.5,"bbox":{"x":67.3828125,"y":-528.3203125,"w":375,"h":528.3203125},"contours":[{"i":[[0,0],[0,0],[0,0],[0,0],[-7.8125,2.6041666666666856],[-8.463541666666657,8.30078125],[-10.7421875,14.973958333333314],[-63.4765625,102.5390625],[0,0],[0,0],[0,0],[11.393229166666686,-9.440104166666686],[0,0],[0,0],[0,0],[0,0],[10.579427083333343,-1.953125],[8.463541666666657,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[9.765625,0],[7.8125,-2.6041666666666856],[8.463541666666657,-8.30078125],[10.7421875,-14.973958333333314],[0,0],[0,0],[0,0],[-30.2734375,44.270833333333314],[0,0],[0,0],[0,0],[0,0],[-6.184895833333343,2.604166666666657],[-10.579427083333343,1.953125],[0,0],[0,0],[0,0]],"v":[[67.3828125,0],[67.3828125,-528.3203125],[155.2734375,-528.3203125],[155.2734375,-296.875],[181.640625,-300.78125],[206.0546875,-317.138671875],[234.86328125,-352.05078125],[346.19140625,-528.3203125],[346.19140625,-528.3203125],[437.98828125,-528.3203125],[332.51953125,-369.62890625],[270.01953125,-289.0625],[270.01953125,-289.0625],[442.3828125,0],[344.7265625,0],[208.984375,-242.67578125],[183.837890625,-235.83984375],[155.2734375,-232.91015625],[155.2734375,-232.91015625],[155.2734375,0]],"c":true}]},"э":{"adv":510.25390625,"bbox":{"x":26.85546875,"y":-538.0859375,"w":440.91796875,"h":547.8515625},"contours":[{"i":[[6.8359375,50.45572916666666],[0,0],[0,0],[-21.647135416666657,-16.92708333333333],[-32.552083333333314,0],[0,0],[-23.111979166666686,28.80859375],[-3.90625,61.848958333333314],[0,0],[0,0],[0,0],[0,0],[21.97265625,27.018229166666686],[44.921875,0],[0,0],[10.416666666666657,-63.802083333333314],[0,0],[0,0],[-36.295572916666664,27.180989583333314],[-55.6640625,0],[0,0],[-39.876302083333314,-46.875],[0,-88.54166666666663],[0,0],[39.876302083333314,-46.54947916666666],[75.52083333333331,0],[0,0],[37.109375,29.296875]],"o":[[0,0],[0,0],[5.208333333333329,35.15625],[21.647135416666657,16.92708333333333],[0,0],[41.9921875,0],[23.111979166666686,-28.80859375],[0,0],[0,0],[0,0],[0,0],[-2.6041666666666856,-61.5234375],[-21.97265625,-27.018229166666686],[0,0],[-68.359375,0],[0,0],[0,0],[9.114583333333329,-48.502604166666686],[36.29557291666666,-27.18098958333337],[0,0],[74.86979166666663,0],[39.876302083333314,46.875],[0,0],[0,89.84375],[-39.876302083333314,46.549479166666664],[0,0],[-57.6171875,0],[-37.109375,-29.296875]],"v":[[26.85546875,-153.80859375],[26.85546875,-153.80859375],[115.72265625,-159.66796875],[156.005859375,-81.54296875],[237.3046875,-56.15234375],[237.3046875,-56.15234375],[334.9609375,-99.365234375],[375.48828125,-235.3515625],[375.48828125,-235.3515625],[173.828125,-235.3515625],[173.828125,-299.31640625],[375.48828125,-299.31640625],[338.623046875,-432.12890625],[238.28125,-472.65625],[238.28125,-472.65625],[120.1171875,-376.953125],[120.1171875,-376.953125],[29.78515625,-383.7890625],[97.900390625,-497.314453125],[235.83984375,-538.0859375],[235.83984375,-538.0859375],[407.958984375,-467.7734375],[467.7734375,-264.6484375],[467.7734375,-264.6484375],[407.958984375,-60.05859375],[234.86328125,9.765625],[234.86328125,9.765625],[92.7734375,-34.1796875]],"c":true}]},"б":{"adv":572.75390625,"bbox":{"x":58.59375,"y":-733.3984375,"w":472.16796875,"h":743.1640625},"contours":[{"i":[[0,65.75520833333331],[0,0],[21.484375,31.087239583333314],[48.502604166666686,0],[0,0],[24.251302083333343,-31.575520833333314],[0,-64.77864583333331],[0,0],[-22.623697916666657,-31.73828125],[-48.50260416666666,0],[0,0],[-22.786458333333314,30.436197916666657]],"o":[[0,0],[0,-65.75520833333331],[-21.484375,-31.087239583333314],[0,0],[-51.7578125,0],[-24.251302083333343,31.575520833333314],[0,0],[0,63.15104166666666],[22.623697916666657,31.73828125],[0,0],[52.408854166666686,0],[22.786458333333314,-30.436197916666657]],"v":[[438.4765625,-245.1171875],[438.4765625,-245.1171875],[406.25,-390.380859375],[301.26953125,-437.01171875],[301.26953125,-437.01171875],[187.255859375,-389.6484375],[150.87890625,-245.1171875],[150.87890625,-245.1171875],[184.814453125,-102.783203125],[291.50390625,-55.17578125],[291.50390625,-55.17578125],[404.296875,-100.830078125]],"c":true},{"i":[[-46.875,0],[0,0],[-34.1796875,-42.48046875],[0,-85.28645833333331],[0,0],[40.690104166666686,-42.15494791666666],[77.47395833333331,0],[0,0],[37.923177083333314,52.408854166666664],[0,108.72395833333331],[0,0],[-7.486979166666664,41.829427083333314],[-15.950520833333329,30.2734375],[-25.227864583333343,20.18229166666663],[-38.24869791666666,12.369791666666629],[-124.34895833333331,17.25260416666663],[0,0],[0,0],[40.201822916666686,-15.950520833333371],[16.276041666666657,-34.83072916666663],[1.3020833333333428,-69.3359375],[0,0],[-32.87760416666666,22.786458333333314]],"o":[[0,0],[72.265625,0],[34.1796875,42.48046875],[0,0],[0,86.26302083333331],[-40.690104166666686,42.154947916666664],[0,0],[-80.078125,0],[-37.92317708333333,-52.40885416666666],[0,0],[0,-55.338541666666686],[7.486979166666671,-41.829427083333314],[15.950520833333329,-30.2734375],[25.227864583333343,-20.18229166666663],[38.248697916666686,-12.369791666666629],[0,0],[0,0],[-136.39322916666663,17.578125],[-40.20182291666666,15.950520833333371],[-16.276041666666657,34.830729166666686],[0,0],[13.997395833333343,-40.690104166666686],[32.87760416666666,-22.786458333333314]],"v":[[319.82421875,-501.46484375],[319.82421875,-501.46484375],[479.4921875,-437.744140625],[530.76171875,-246.09375],[530.76171875,-246.09375],[469.7265625,-53.466796875],[292.48046875,9.765625],[292.48046875,9.765625],[115.478515625,-68.84765625],[58.59375,-310.546875],[58.59375,-310.546875],[69.82421875,-456.298828125],[104.98046875,-564.453125],[166.748046875,-640.13671875],[261.962890625,-688.96484375],[505.859375,-733.3984375],[505.859375,-733.3984375],[505.859375,-654.78515625],[240.966796875,-604.4921875],[156.25,-528.3203125],[129.8828125,-372.0703125],[129.8828125,-372.0703125],[200.1953125,-467.28515625]],"c":true}]},"л":{"adv":583.49609375,"bbox":{"x":5.37109375,"y":-528.3203125,"w":508.7890625,"h":538.0859375},"contours":[{"i":[[0,0],[0,0],[0,0],[0,0],[10.416666666666657,-49.641927083333314],[12.044270833333343,-25.390625],[17.740885416666657,-12.044270833333332],[27.994791666666657,0],[0,0],[14.322916666666664,4.231770833333333],[0,0],[0,0],[-13.997395833333332,0],[0,0],[-10.904947916666671,17.90364583333333],[-8.951822916666671,43.9453125],[-11.393229166666657,85.9375],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[-19.205729166666657,141.92708333333331],[-10.416666666666657,49.64192708333333],[-12.044270833333343,25.390625],[-17.740885416666657,12.044270833333332],[0,0],[-16.276041666666664,0],[0,0],[0,0],[8.138020833333332,2.9296875],[0,0],[17.90364583333333,0],[10.904947916666671,-17.90364583333333],[8.951822916666671,-43.9453125],[0,0],[0,0],[0,0],[0,0]],"v":[[514.16015625,0],[425.78125,0],[425.78125,-464.35546875],[242.67578125,-464.35546875],[198.2421875,-177.001953125],[164.55078125,-64.453125],[119.873046875,-8.30078125],[51.26953125,9.765625],[51.26953125,9.765625],[5.37109375,3.41796875],[5.37109375,3.41796875],[5.37109375,-59.5703125],[38.57421875,-55.17578125],[38.57421875,-55.17578125],[81.787109375,-82.03125],[111.572265625,-174.8046875],[142.08984375,-369.62890625],[142.08984375,-369.62890625],[163.57421875,-528.3203125],[514.16015625,-528.3203125]],"c":true}]},"—":{"adv":1000,"bbox":{"x":0,"y":-287.109375,"w":1000,"h":66.89453125},"contours":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1000,-220.21484375],[0,-220.21484375],[0,-287.109375],[1000,-287.109375]],"c":true}]},"г":{"adv":364.74609375,"bbox":{"x":69.3359375,"y":-528.3203125,"w":266.11328125,"h":528.3203125},"contours":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[69.3359375,-528.3203125],[335.44921875,-528.3203125],[335.44921875,-464.35546875],[157.2265625,-464.35546875],[157.2265625,0],[69.3359375,0]],"c":true}]},"а":{"adv":556.15234375,"bbox":{"x":42.48046875,"y":-538.0859375,"w":513.671875,"h":547.8515625},"contours":[{"i":[[42.64322916666666,0],[0,0],[26.69270833333333,27.994791666666664],[0,48.828125],[0,0],[-35.97005208333333,29.296875],[-80.078125,1.953125],[0,0],[0,0],[0,0],[18.229166666666686,18.5546875],[39.0625,0],[0,0],[17.903645833333343,-13.346354166666686],[3.580729166666657,-29.296875],[0,0],[0,0],[-126.30208333333331,0],[0,0],[-33.528645833333314,-30.43619791666663],[0,-57.6171875],[0,0],[0,0],[-6.8359375,-13.18359375],[-19.205729166666686,0],[0,0],[-10.7421875,2.2786458333333357],[0,0],[0,0],[23.111979166666686,0],[0,0],[14.811197916666686,17.08984375],[1.953125,36.45833333333333],[0,0],[0,0],[29.78515625,-16.764322916666664]],"o":[[0,0],[-53.059895833333314,0],[-26.69270833333333,-27.994791666666664],[0,0],[0,-54.6875],[35.970052083333314,-29.296875],[0,0],[0,0],[0,0],[0,-42.96875],[-18.229166666666686,-18.5546875],[0,0],[-39.388020833333314,0],[-17.903645833333343,13.346354166666686],[0,0],[0,0],[14.973958333333329,-95.05208333333331],[0,0],[66.40625,0],[33.528645833333314,30.436197916666686],[0,0],[0,0],[0,26.041666666666657],[6.8359375,13.18359375],[0,0],[8.463541666666629,0],[0,0],[0,0],[-22.13541666666663,5.208333333333333],[0,0],[-32.552083333333314,0],[-14.811197916666686,-17.08984375],[0,0],[0,0],[-22.4609375,40.36458333333333],[-29.78515625,16.764322916666664]],"v":[[202.1484375,9.765625],[202.1484375,9.765625],[82.51953125,-32.2265625],[42.48046875,-147.4609375],[42.48046875,-147.4609375],[96.435546875,-273.4375],[270.5078125,-320.3125],[270.5078125,-320.3125],[389.16015625,-322.265625],[389.16015625,-351.07421875],[361.81640625,-443.359375],[275.87890625,-471.19140625],[275.87890625,-471.19140625],[189.94140625,-451.171875],[157.71484375,-387.20703125],[157.71484375,-387.20703125],[65.91796875,-395.5078125],[277.83203125,-538.0859375],[277.83203125,-538.0859375],[427.734375,-492.431640625],[478.02734375,-360.3515625],[478.02734375,-360.3515625],[478.02734375,-132.8125],[488.28125,-73.974609375],[527.34375,-54.19921875],[527.34375,-54.19921875],[556.15234375,-57.6171875],[556.15234375,-57.6171875],[556.15234375,-2.9296875],[488.28125,4.8828125],[488.28125,4.8828125],[417.236328125,-20.751953125],[392.08984375,-101.07421875],[392.08984375,-101.07421875],[389.16015625,-101.07421875],[310.791015625,-15.380859375]],"c":true},{"i":[[-28.645833333333343,0],[0,0],[-25.065104166666686,14.6484375],[-14.485677083333314,25.553385416666657],[0,27.018229166666657],[0,0],[0,0],[0,0],[21.321614583333343,-7.8125],[11.393229166666657,-16.276041666666657],[0,-26.3671875],[0,0],[-15.462239583333343,-15.625]],"o":[[0,0],[32.2265625,0],[25.065104166666686,-14.6484375],[14.485677083333314,-25.553385416666657],[0,0],[0,0],[0,0],[-41.341145833333314,0.6510416666666856],[-21.321614583333343,7.8125],[-11.393229166666657,16.276041666666657],[0,0],[0,28.64583333333333],[15.462239583333343,15.625]],"v":[[222.16796875,-56.15234375],[222.16796875,-56.15234375],[308.10546875,-78.125],[367.431640625,-138.427734375],[389.16015625,-217.28515625],[389.16015625,-217.28515625],[389.16015625,-260.7421875],[292.96875,-258.7890625],[198.974609375,-246.09375],[149.90234375,-209.9609375],[132.8125,-145.99609375],[132.8125,-145.99609375],[156.005859375,-79.58984375]],"c":true}]}," ":{"adv":277.83203125,"bbox":{"x":0,"y":0,"w":0,"h":0},"contours":[]},"в":{"adv":531.25,"bbox":{"x":69.3359375,"y":-528.3203125,"w":418.45703125,"h":528.3203125},"contours":[{"i":[[0,0],[0,0],[-32.552083333333314,-22.78645833333337],[0,-42.643229166666686],[0,0],[18.5546875,-20.182291666666686],[35.481770833333314,-6.8359375],[0,0],[0,0],[-20.99609375,-21.158854166666686],[0,-34.83072916666666],[0,0],[35.64453125,-26.85546875],[62.825520833333314,0],[0,0],[0,0]],"o":[[0,0],[65.10416666666663,0],[32.552083333333314,22.786458333333314],[0,0],[0,30.2734375],[-18.5546875,20.182291666666686],[0,0],[0,0],[41.9921875,5.533854166666686],[20.99609375,21.158854166666657],[0,0],[0,47.8515625],[-35.64453125,26.85546875],[0,0],[0,0],[0,0]],"v":[[69.3359375,-528.3203125],[275.390625,-528.3203125],[421.875,-494.140625],[470.703125,-395.99609375],[470.703125,-395.99609375],[442.87109375,-320.3125],[361.81640625,-279.78515625],[361.81640625,-279.78515625],[361.81640625,-276.3671875],[456.298828125,-236.328125],[487.79296875,-152.34375],[487.79296875,-152.34375],[434.326171875,-40.283203125],[286.62109375,0],[286.62109375,0],[69.3359375,0]],"c":true},{"i":[[0,0],[0,0],[0,0],[-18.229166666666686,13.834635416666671],[0,30.2734375],[0,0],[19.368489583333314,13.509114583333343],[46.549479166666686,0],[0,0]],"o":[[0,0],[0,0],[44.921875,0],[18.229166666666686,-13.834635416666671],[0,0],[0,-32.87760416666666],[-19.368489583333314,-13.509114583333343],[0,0],[0,0]],"v":[[157.2265625,-241.69921875],[157.2265625,-64.94140625],[272.4609375,-64.94140625],[367.1875,-85.693359375],[394.53125,-151.85546875],[394.53125,-151.85546875],[365.478515625,-221.435546875],[266.6015625,-241.69921875],[266.6015625,-241.69921875]],"c":true},{"i":[[0,0],[0,0],[0,0],[0,0],[-17.740885416666686,11.71875],[0,29.296875],[0,0],[16.6015625,12.369791666666686],[39.388020833333314,0]],"o":[[0,0],[0,0],[0,0],[41.666666666666686,0],[17.740885416666686,-11.71875],[0,0],[0,-26.692708333333314],[-16.6015625,-12.369791666666686],[0,0]],"v":[[269.53125,-461.42578125],[157.2265625,-461.42578125],[157.2265625,-305.17578125],[262.6953125,-305.17578125],[351.806640625,-322.75390625],[378.41796875,-384.27734375],[378.41796875,-384.27734375],[353.515625,-442.87109375],[269.53125,-461.42578125]],"c":true}]},"с":{"adv":500,"bbox":{"x":42.48046875,"y":-538.0859375,"w":431.15234375,"h":547.8515625},"contours":[{"i":[[0,-73.2421875],[0,0],[-22.135416666666657,-33.85416666666666],[-44.59635416666666,0],[0,0],[-20.99609375,16.92708333333333],[-4.8828125,35.15625],[0,0],[0,0],[36.458333333333314,-30.2734375],[55.989583333333314,0],[0,0],[38.899739583333314,46.71223958333333],[0,89.51822916666666],[0,0],[-39.0625,46.712239583333314],[-72.91666666666666,0],[0,0],[-35.64453125,-27.99479166666663],[-9.114583333333314,-49.153645833333314],[0,0],[0,0],[18.5546875,17.252604166666686],[34.1796875,0],[0,0],[20.833333333333343,-30.924479166666686]],"o":[[0,0],[0,70.3125],[22.135416666666657,33.85416666666666],[0,0],[31.25,0],[20.99609375,-16.92708333333333],[0,0],[0,0],[-6.8359375,50.78125],[-36.458333333333314,30.2734375],[0,0],[-73.89322916666666,0],[-38.89973958333333,-46.71223958333333],[0,0],[0,-88.8671875],[39.0625,-46.71223958333337],[0,0],[54.036458333333314,0],[35.64453125,27.994791666666686],[0,0],[0,0],[-4.557291666666686,-29.296875],[-18.5546875,-17.252604166666686],[0,0],[-46.54947916666666,0],[-20.833333333333343,30.924479166666686]],"v":[[134.27734375,-266.6015625],[134.27734375,-266.6015625],[167.48046875,-110.3515625],[267.578125,-59.5703125],[267.578125,-59.5703125],[345.947265625,-84.9609375],[384.765625,-163.0859375],[384.765625,-163.0859375],[473.6328125,-157.2265625],[408.69140625,-35.64453125],[270.01953125,9.765625],[270.01953125,9.765625],[100.830078125,-60.302734375],[42.48046875,-264.6484375],[42.48046875,-264.6484375],[101.07421875,-468.017578125],[269.04296875,-538.0859375],[269.04296875,-538.0859375],[403.564453125,-496.09375],[470.703125,-380.37109375],[470.703125,-380.37109375],[380.37109375,-373.53515625],[345.703125,-443.359375],[266.6015625,-469.23828125],[266.6015625,-469.23828125],[165.52734375,-422.8515625]],"c":true}]},"о":{"adv":556.15234375,"bbox":{"x":41.9921875,"y":-538.0859375,"w":472.16796875,"h":547.8515625},"contours":[{"i":[[0,-93.42447916666663],[0,0],[40.690104166666686,-45.24739583333333],[77.47395833333331,0],[0,0],[39.388020833333314,47.037760416666664],[0,88.8671875],[0,0],[-157.87760416666666,0],[0,0],[-38.0859375,-44.43359375]],"o":[[0,0],[0,92.44791666666666],[-40.690104166666686,45.24739583333333],[0,0],[-77.1484375,0],[-39.38802083333333,-47.03776041666666],[0,0],[0,-182.29166666666663],[0,0],[80.72916666666663,0],[38.0859375,44.43359375]],"v":[[514.16015625,-264.6484375],[514.16015625,-264.6484375],[453.125,-58.10546875],[275.87890625,9.765625],[275.87890625,9.765625],[101.07421875,-60.791015625],[41.9921875,-264.6484375],[41.9921875,-264.6484375],[278.80859375,-538.0859375],[278.80859375,-538.0859375],[457.03125,-471.435546875]],"c":true},{"i":[[0,71.94010416666666],[0,0],[21.647135416666686,33.040364583333314],[51.106770833333314,0],[0,0],[22.94921875,-33.69140625],[0,-71.61458333333331],[0,0],[-22.623697916666657,-34.993489583333314],[-48.50260416666666,0],[0,0],[-22.623697916666686,33.85416666666666]],"o":[[0,0],[0,-72.91666666666663],[-21.647135416666686,-33.040364583333314],[0,0],[-51.43229166666666,0],[-22.94921875,33.69140625],[0,0],[0,69.66145833333331],[22.623697916666657,34.99348958333333],[0,0],[52.734375,0],[22.623697916666686,-33.85416666666666]],"v":[[421.875,-264.6484375],[421.875,-264.6484375],[389.404296875,-423.583984375],[280.2734375,-473.14453125],[280.2734375,-473.14453125],[168.701171875,-422.607421875],[134.27734375,-264.6484375],[134.27734375,-264.6484375],[168.212890625,-107.666015625],[274.90234375,-55.17578125],[274.90234375,-55.17578125],[387.939453125,-105.95703125]],"c":true}]}}} \ No newline at end of file diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 2656fd0..a5cd761 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1099,7 +1099,14 @@ parameters from the URL and the gateway verifies them in-process — §12); a st gateway's `/` 308-redirects to `/app/`. The **landing** ships in its own static container: the `landing` target of `gateway/Dockerfile` (caddy:2-alpine + the same Vite build, `deploy/landing/Caddyfile`) serves it at `/`, so stray public traffic is absorbed by -static file serving and never reaches the Go edge. Hash-named `/assets/*` are served +static file serving and never reaches the Go edge. The landing shell carries the site's +static SEO head — Russian title/description, the Open Graph card (Telegram/VK link +previews), JSON-LD and a canonical link — with absolute URLs pinned to the production +origin, so the test contour canonicalises to production instead of being indexed as a +separate site; the SPA shell is `noindex`, and the landing always boots in Russian (no +browser-language detection — crawlers render with arbitrary languages). The favicon set, +`og-image.png` and `robots.txt` ship unhashed from `ui/public/` (generated by +`assets/icons/`, same tile design as the VK loader). Hash-named `/assets/*` are served `immutable` (a relaunch is a cache hit, not a re-download); the HTML shells are `no-cache` so a new deploy is picked up — both containers apply the same caching. An in-compose **caddy** is the contour's edge: it owns a single `/_gm` Basic-Auth and diff --git a/docs/FUNCTIONAL.md b/docs/FUNCTIONAL.md index be03167..2b0af0d 100644 --- a/docs/FUNCTIONAL.md +++ b/docs/FUNCTIONAL.md @@ -23,7 +23,13 @@ variant's alphabet, remembers answers within the session and rate-limits repeats A public **landing page** at the site root introduces the game, switches language and theme, and links to the Telegram game channel and the VK Mini App; the game itself runs at `/app/` (web), `/telegram/` (the Telegram Mini App) and `/vk/` (the VK Mini App). The landing's theme is ephemeral -(it follows the system scheme, not the saved preference); its language choice is saved. +(it follows the system scheme, not the saved preference); its language choice is saved. The +landing always opens in **Russian** — the browser language is never auto-detected (crawlers +render with arbitrary languages, so detection would make the indexed content +nondeterministic); a saved 🌐 choice still wins. The page carries a static Russian SEO head +(title/description, the Open Graph card Telegram/VK link previews use, a canonical link +pinned to the production origin, JSON-LD, the favicon set and `robots.txt`), while the SPA +shell is `noindex` — the landing is the only indexable page. ### First-run onboarding The first time a player opens the app it walks them through the interface with a light diff --git a/docs/FUNCTIONAL_ru.md b/docs/FUNCTIONAL_ru.md index 887eaf7..5bb3c73 100644 --- a/docs/FUNCTIONAL_ru.md +++ b/docs/FUNCTIONAL_ru.md @@ -24,7 +24,14 @@ top-1 подсказку, безлимитную проверку слова с Публичная **посадочная страница** в корне сайта представляет игру, переключает язык и тему и ведёт в Telegram-канал игры и в VK Mini App; сама игра живёт по адресам `/app/` (веб), `/telegram/` (Telegram Mini App) и `/vk/` (VK Mini App). Тема на странице эфемерна (берётся из -системной настройки, а не из сохранённой), выбор языка сохраняется. +системной настройки, а не из сохранённой), выбор языка сохраняется. Страница всегда +открывается на **русском** — язык браузера не определяется автоматически (роботы +рендерят страницу с произвольным языком, и автоопределение сделало бы +проиндексированный контент недетерминированным); сохранённый выбор 🌐 по-прежнему +главнее. Страница несёт статическую русскую SEO-«шапку» (title/description, карточка +Open Graph, которую используют превью ссылок в Telegram/VK, канонический адрес +продакшен-домена, JSON-LD, набор favicon и `robots.txt`), а оболочка SPA помечена +`noindex` — индексируется только посадочная страница. ### Первый запуск: онбординг При первом открытии приложения игрока один раз проводят по интерфейсу лёгким diff --git a/ui/e2e/landing.spec.ts b/ui/e2e/landing.spec.ts index d6177ad..e6a5ab6 100644 --- a/ui/e2e/landing.spec.ts +++ b/ui/e2e/landing.spec.ts @@ -2,16 +2,29 @@ import { expect, test } from './fixtures'; // The landing page is a separate Vite entry (landing.html), served at "/" in production while // the game SPA lives at /app/ and /telegram/. In dev it is reachable at /landing.html. -test('landing shows the pitch, switches language via the dropdown, and toggles theme', async ({ page }) => { +test('landing defaults to Russian, switches language via the dropdown, and toggles theme', async ({ page }) => { await page.goto('/landing.html'); - // The tagline renders (English in the default test browser). - await expect(page.getByText(/Play Scrabble/i)).toBeVisible(); - - // The language dropdown switches the copy to Russian. - await page.getByRole('button', { name: 'Language' }).click(); - await page.getByRole('menuitem', { name: /Русский/ }).click(); + // Russian by default regardless of the browser language (the test browser is en-US): + // crawlers render with arbitrary navigator.language, so the landing never auto-detects. await expect(page.getByText(/Играй в «Эрудита»/)).toBeVisible(); + await expect(page).toHaveTitle(/Эрудит \(Скрэббл\)/); + expect(await page.evaluate(() => document.documentElement.lang)).toBe('ru'); + + // The static SEO head is present (the page is client-rendered; this layer is what + // non-rendering crawlers and link-preview bots see). + expect(await page.locator('meta[name="description"]').getAttribute('content')).toContain('Эрудит'); + expect(await page.locator('meta[property="og:image"]').getAttribute('content')).toBe( + 'https://erudit-game.ru/og-image.png', + ); + const jsonLd = await page.locator('script[type="application/ld+json"]').textContent(); + expect(JSON.parse(jsonLd!)['@type']).toBe('WebApplication'); + + // The language dropdown switches the copy to English, and the document language follows. + await page.getByRole('button', { name: 'Language' }).click(); + await page.getByRole('menuitem', { name: /English/ }).click(); + await expect(page.getByText(/Play Scrabble/i)).toBeVisible(); + expect(await page.evaluate(() => document.documentElement.lang)).toBe('en'); // The theme toggle flips the document theme (ephemeral, light<->dark). const before = await page.evaluate(() => document.documentElement.getAttribute('data-theme')); @@ -24,7 +37,7 @@ test('landing shows the pitch, switches language via the dropdown, and toggles t // adds .app-shell); the landing is a normal scrolling document and must keep scrolling. test('the landing is a normal scrolling document (the SPA document-pin does not apply)', async ({ page }) => { await page.goto('/landing.html'); - await expect(page.getByText(/Play Scrabble/i)).toBeVisible(); + await expect(page.getByText(/Играй в «Эрудита»/)).toBeVisible(); const state = await page.evaluate(() => ({ shell: document.documentElement.classList.contains('app-shell'), diff --git a/ui/index.html b/ui/index.html index 8eac93b..e6167a2 100644 --- a/ui/index.html +++ b/ui/index.html @@ -1,7 +1,11 @@ - + + + + + +
diff --git a/ui/landing.html b/ui/landing.html index b92f035..9e25e53 100644 --- a/ui/landing.html +++ b/ui/landing.html @@ -1,10 +1,51 @@ - + - Scrabble + + Эрудит (Скрэббл) — играть онлайн с друзьями или роботом + + + + + + + + + + + + + + + + + + + +
diff --git a/ui/public/apple-touch-icon.png b/ui/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ba28ea8b305118c8b1b895b92401850c71b5a597 GIT binary patch literal 6405 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 diff --git a/ui/public/og-image.png b/ui/public/og-image.png new file mode 100644 index 0000000000000000000000000000000000000000..65bb19f23a70f7acd6537db35069dc6db33d6fbc GIT binary patch literal 43130 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 import { onMount } from 'svelte'; import { applyTheme } from './lib/theme'; - import { i18n, localeFrom, setLocale, t, type Locale } from './lib/i18n/index.svelte'; + import { i18n, setLocale, t, type Locale } from './lib/i18n/index.svelte'; import { loadPrefs, savePrefs, type Prefs } from './lib/session'; import { aboutContent } from './lib/aboutContent'; import { telegramChannelLink, vkAppLink } from './lib/landing'; @@ -9,7 +9,8 @@ // Standalone landing page, the public entry at "/" (the game SPA lives at /app/ and // /telegram/). It reuses the app's theme/i18n/prefs leaf modules — not the app store — so it // stays light. Theme is EPHEMERAL here (no auto, no persistence): it starts from the system - // scheme and the icon toggles light<->dark in memory. Language IS persisted (synced with the app). + // scheme and the icon toggles light<->dark in memory. Language IS persisted (synced with the + // app) but defaults to Russian, never to the browser language — see landing.ts. let theme = $state<'light' | 'dark'>('light'); let langOpen = $state(false); @@ -31,7 +32,13 @@ prefs = await loadPrefs(); theme = systemTheme(); applyTheme(theme); - setLocale(prefs.locale ?? localeFrom(typeof navigator !== 'undefined' ? navigator.language : 'en')); + setLocale(prefs.locale ?? 'ru'); + }); + + // Keep the document language honest for assistive tech and crawlers: the static shell + // declares lang="ru" (the default), and a 🌐 switch to English must follow. + $effect(() => { + document.documentElement.lang = i18n.locale; }); function toggleTheme(): void { diff --git a/ui/src/landing.ts b/ui/src/landing.ts index 2b0c25e..ff86050 100644 --- a/ui/src/landing.ts +++ b/ui/src/landing.ts @@ -1,7 +1,16 @@ import { mount } from 'svelte'; import './app.css'; +import { setLocale } from './lib/i18n/index.svelte'; import Landing from './Landing.svelte'; // Entry for the standalone landing page (served at "/" by the gateway; the game SPA lives at // /app/ and /telegram/). Mounts into the same #app node as the SPA's main.ts. + +// The landing always starts in Russian — the primary audience and the language of the +// static SEO head (crawlers render with arbitrary navigator.language, e.g. Googlebot's +// en-US, so browser detection would make the indexed content nondeterministic). Set +// before mount so the very first paint is Russian; a saved 🌐 choice is applied in +// Landing's onMount once prefs load. +setLocale('ru'); + export default mount(Landing, { target: document.getElementById('app')! });