core-maugli 1.2.2 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +29 -15
  2. package/package.json +6 -13
  3. package/public/img/examples/blog/previews/post-1-avtomatizaciya-marketinga-kak-ii-osvobozhdaet-predprinimatelei-ot-cifrovogo-rabstva.webp +0 -0
  4. package/public/img/examples/blog/previews/post-2-avtomatizaciya-kontenta-kak-neiroseti-ubivayut-perfekcionizm-v-biznese.webp +0 -0
  5. package/public/img/examples/blog/previews/post-3-laik-ne-valyuta-kak-avtomatizaciya-marketinga-spasaet-ot-lozhnyh-metrik.webp +0 -0
  6. package/public/img/examples/blog/previews/post-5-5-fatalnyh-oshibok-marketinga-kotorye-ubivayut-startapy-na-starte.webp +0 -0
  7. package/public/img/examples/blog/previews/post-6-5-strategii-kontent-marketinga-dlya-startapov-avtomatizaciya-i-revolyuciya.webp +0 -0
  8. package/public/img/examples/blog/previews/post-7-viralnyi-kontent-ne-udacha-a-strategiya-avtomatizaciya-marketinga.webp +0 -0
  9. package/public/img/examples/blog/previews/post-agent-experience-mcp-biznes-v-epohu-ii-agentov.webp +0 -0
  10. package/public/img/examples/blog/previews/post_11.webp +0 -0
  11. package/public/img/examples/blog/previews/post_12.webp +0 -0
  12. package/public/img/examples/blog/previews/post_1_jsonld_guide.webp +0 -0
  13. package/public/img/examples/blog/previews/test-post.webp +0 -0
  14. package/public/img/examples/blog/previews/tr-post-1.webp +0 -0
  15. package/public/img/examples/products/previews/product_1.webp +0 -0
  16. package/public/img/examples/products/previews/product_2.webp +0 -0
  17. package/public/img/examples/projects/previews/project_1.webp +0 -0
  18. package/public/img/examples/projects/previews/project_2.webp +0 -0
  19. package/scripts/generate-previews.js +175 -0
  20. package/scripts/update-components.js +166 -0
  21. package/scripts/upgrade-config.js +23 -3
  22. package/src/components/LanguageSwitcher.astro +2 -16
  23. package/astro.config.mjs +0 -92
  24. package/bin/init.js +0 -201
  25. package/public/img/default/autor_default.webp +0 -0
  26. package/public/img/default/blog_default.webp +0 -0
  27. package/public/img/default/default.webp +0 -0
  28. package/public/img/default/product_default.webp +0 -0
  29. package/public/img/default/project_default.webp +0 -0
  30. package/public/img/default/rubric_default.webp +0 -0
  31. package/public/img/default/test.webp +0 -0
  32. package/public/img/default/test2.webp +0 -0
  33. package/resize-all.cjs +0 -29
  34. package/src/i18n/de.json +0 -126
  35. package/src/i18n/en.json +0 -126
  36. package/src/i18n/es.json +0 -126
  37. package/src/i18n/fr.json +0 -126
  38. package/src/i18n/index.ts +0 -10
  39. package/src/i18n/ja.json +0 -126
  40. package/src/i18n/languages.ts +0 -23
  41. package/src/i18n/pt.json +0 -126
  42. package/src/i18n/ru.json +0 -123
  43. package/src/i18n/zh.json +0 -126
  44. package/src/icons/ArrowLeft.astro +0 -13
  45. package/src/icons/ArrowRight.astro +0 -13
  46. package/src/icons/flags/brazil.svg +0 -14
  47. package/src/icons/flags/china.svg +0 -15
  48. package/src/icons/flags/france.svg +0 -12
  49. package/src/icons/flags/germany.svg +0 -12
  50. package/src/icons/flags/japan.svg +0 -11
  51. package/src/icons/flags/russia.svg +0 -12
  52. package/src/icons/flags/spain.svg +0 -12
  53. package/src/icons/flags/united arab emirates.svg +0 -13
  54. package/src/icons/flags/united states.svg +0 -15
  55. package/src/icons/socials/BlueskyIcon.astro +0 -9
  56. package/src/icons/socials/EmailIcon.astro +0 -8
  57. package/src/icons/socials/LinkedinIcon.astro +0 -9
  58. package/src/icons/socials/MastodonIcon.astro +0 -9
  59. package/src/icons/socials/MediumIcon.astro +0 -9
  60. package/src/icons/socials/RedditIcon.astro +0 -11
  61. package/src/icons/socials/TelegramIcon.astro +0 -11
  62. package/src/icons/socials/TwitterIcon.astro +0 -9
  63. package/src/layouts/BaseLayout.astro +0 -59
  64. package/src/pages/404.astro +0 -24
  65. package/src/pages/[...id].astro +0 -50
  66. package/src/pages/about.astro +0 -0
  67. package/src/pages/authors/[...page].astro +0 -105
  68. package/src/pages/authors/[id].astro +0 -175
  69. package/src/pages/blog/[...page].astro +0 -59
  70. package/src/pages/blog/[id].astro +0 -175
  71. package/src/pages/index.astro +0 -90
  72. package/src/pages/products/[...page].astro +0 -50
  73. package/src/pages/products/[id].astro +0 -221
  74. package/src/pages/projects/[...page].astro +0 -74
  75. package/src/pages/projects/[id].astro +0 -165
  76. package/src/pages/projects/tags/[id]/[...page].astro +0 -58
  77. package/src/pages/rss.xml.js +0 -5
  78. package/src/pages/tags/[id]/[...page].astro +0 -110
  79. package/src/pages/tags/index.astro +0 -124
  80. package/src/scripts/infoCardFadeIn.js +0 -22
  81. package/src/styles/global.css +0 -273
  82. package/src/utils/common-utils.ts +0 -0
  83. package/src/utils/content-loader.ts +0 -14
  84. package/src/utils/data-utils.ts +0 -49
  85. package/src/utils/featuredManager.ts +0 -118
  86. package/src/utils/posts.ts +0 -43
  87. package/src/utils/reading-time.ts +0 -28
  88. package/src/utils/remark-slugify.js +0 -8
  89. package/src/utils/rss.ts +0 -23
  90. package/tsconfig.json +0 -8
  91. package/typograf-batch.js +0 -49
  92. package/vite.config.js +0 -11
package/astro.config.mjs DELETED
@@ -1,92 +0,0 @@
1
- import mdx from '@astrojs/mdx';
2
- import sitemap from '@astrojs/sitemap';
3
- import tailwindcss from '@tailwindcss/vite';
4
- import { defineConfig } from 'astro/config';
5
- import { imagetools } from 'vite-imagetools';
6
- import { VitePWA } from 'vite-plugin-pwa';
7
- import siteConfig from './src/data/site-config';
8
- import remarkSlug from 'remark-slug';
9
- import customSlugify from './src/utils/remark-slugify';
10
- import { maugliConfig } from './src/config/maugli.config';
11
-
12
- export const pwaOptions = {
13
- registerType: 'autoUpdate',
14
- includeAssets: ['favicon.svg', 'favicon.ico', 'robots.txt', 'apple-touch-icon.png'],
15
- manifest: {
16
- name: "Maugli Blog",
17
- short_name: "Maugli",
18
- start_url: "/",
19
- display: "standalone",
20
- background_color: maugliConfig.pwa?.backgroundColor ?? '#ffffff',
21
- theme_color: maugliConfig.pwa?.themeColor ?? '#0cbf11',
22
- icons: maugliConfig.pwa?.icons ?? [
23
- {
24
- src: "/icon-192.png",
25
- sizes: "192x192",
26
- type: "image/png",
27
- purpose: "any maskable",
28
- },
29
- {
30
- src: "/icon-512.png",
31
- sizes: "512x512",
32
- type: "image/png",
33
- },
34
- ],
35
- },
36
- workbox: {
37
- navigateFallback: '/index.html',
38
- cleanupOutdatedCaches: true,
39
- navigateFallbackDenylist: [/^\/api\//],
40
- clientsClaim: true,
41
- globPatterns: ['**/*.{js,css,html,png,jpg,jpeg,webp,svg}'],
42
- runtimeCaching: [
43
- {
44
- urlPattern: ({ request }) => request.destination === 'image',
45
- handler: 'CacheFirst',
46
- options: {
47
- cacheName: 'images-cache',
48
- expiration: {
49
- maxEntries: 50,
50
- maxAgeSeconds: 30 * 24 * 60 * 60 // 30 дней
51
- }
52
- }
53
- },
54
- {
55
- urlPattern: ({ request }) => request.destination === 'font',
56
- handler: 'CacheFirst',
57
- options: {
58
- cacheName: 'fonts-cache',
59
- expiration: {
60
- maxEntries: 20,
61
- maxAgeSeconds: 365 * 24 * 60 * 60 // 1 год
62
- }
63
- }
64
- }
65
- ]
66
- },
67
- devOptions: {
68
- enabled: true, // чтобы работал в деве
69
- type: 'module',
70
- }
71
- };
72
-
73
- // https://astro.build/config
74
- export default defineConfig({
75
- site: siteConfig.website,
76
- integrations: [
77
- mdx(),
78
- sitemap()
79
- ],
80
- vite: {
81
- plugins: [
82
- tailwindcss(),
83
- imagetools(),
84
- VitePWA(pwaOptions)
85
- ]
86
- },
87
- markdown: {
88
- remarkPlugins: [
89
- [remarkSlug, { slug: customSlugify }]
90
- ]
91
- }
92
- });
package/bin/init.js DELETED
@@ -1,201 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { execSync } from 'child_process';
4
- import { cpSync, existsSync, readFileSync, writeFileSync } from 'fs';
5
- import path from 'path';
6
- import readline from 'readline';
7
- import { fileURLToPath } from 'url';
8
-
9
- const __filename = fileURLToPath(import.meta.url);
10
- const __dirname = path.dirname(__filename);
11
- const templateRoot = path.join(__dirname, '..');
12
-
13
- function getLanguageCodes() {
14
- const file = readFileSync(path.join(templateRoot, 'src/i18n/languages.ts'), 'utf8');
15
- const codes = [];
16
- const regex = /{\s*code:\s*'([^']+)'/g;
17
- let match;
18
- while ((match = regex.exec(file)) !== null) {
19
- codes.push(match[1]);
20
- }
21
- return codes;
22
- }
23
-
24
- function promptLang(codes) {
25
- return new Promise(resolve => {
26
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
27
- rl.question(`Choose language (${codes.join(', ')}): `, answer => {
28
- rl.close();
29
- resolve(codes.includes(answer) ? answer : codes[0]);
30
- });
31
- });
32
- }
33
-
34
- function promptRepo() {
35
- return new Promise(resolve => {
36
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
37
- rl.question('Repository URL: ', answer => {
38
- rl.close();
39
- resolve(answer.trim());
40
- });
41
- });
42
- }
43
-
44
- async function getRepoUrl(targetDir, repoOption) {
45
- if (repoOption) return repoOption;
46
- try {
47
- const url = execSync('git remote get-url origin', {
48
- cwd: targetDir,
49
- stdio: ['ignore', 'pipe', 'ignore']
50
- })
51
- .toString()
52
- .trim();
53
- if (url) return url;
54
- } catch {
55
- // ignore
56
- }
57
- return await promptRepo();
58
- }
59
-
60
- function updateReadme(targetDir, repoUrl) {
61
- if (!repoUrl) return;
62
- const readmePath = path.join(targetDir, 'README.md');
63
- if (!existsSync(readmePath)) return;
64
- let content = readFileSync(readmePath, 'utf8');
65
- const pattern = /https:\/\/app\.netlify\.com\/start\/deploy\?repository=[^\)\s]+/;
66
- content = content.replace(
67
- pattern,
68
- `https://app.netlify.com/start/deploy?repository=${repoUrl}`
69
- );
70
- writeFileSync(readmePath, content);
71
- console.log('Updated Netlify link in README.md');
72
- }
73
-
74
- function updateConfig(targetDir, lang, repoUrl) {
75
- const configPath = path.join(targetDir, 'src', 'config', 'maugli.config.ts');
76
- if (!existsSync(configPath)) return;
77
- let content = readFileSync(configPath, 'utf8');
78
- content = content.replace(/defaultLang:\s*'[^']*'/, `defaultLang: '${lang}'`);
79
- const multiMatch = content.match(/enableMultiLang:\s*(true|false)/);
80
- const multi = multiMatch ? multiMatch[1] === 'true' : false;
81
- content = content.replace(/showLangSwitcher:\s*(true|false)/, `showLangSwitcher: ${multi}`);
82
-
83
- // Update repository URL if provided
84
- if (repoUrl) {
85
- content = content.replace(
86
- /repository:\s*{[^}]*url:\s*'[^']*'/,
87
- `repository: {\n url: '${repoUrl}'`
88
- );
89
- }
90
-
91
- writeFileSync(configPath, content);
92
- console.log(`Configured default language to ${lang}`);
93
- if (repoUrl) {
94
- console.log(`Configured repository URL to ${repoUrl}`);
95
- }
96
- }
97
-
98
- export default async function init(targetName, langOption, repoOption) {
99
- const targetDir = targetName ? path.resolve(targetName) : process.cwd();
100
- const codes = getLanguageCodes();
101
- const lang = langOption && codes.includes(langOption) ? langOption : await promptLang(codes);
102
-
103
- function copyItem(item) {
104
- const src = path.join(templateRoot, item);
105
- const dest = path.join(targetDir, item);
106
-
107
- if (!existsSync(src)) {
108
- console.log(`Skipped ${item} (not found)`);
109
- return;
110
- }
111
-
112
- cpSync(src, dest, { recursive: true });
113
- console.log(`Copied ${item}`);
114
- }
115
-
116
- // Copy package files first so npm install works correctly
117
- ['package.json', 'package-lock.json'].forEach(file => {
118
- if (existsSync(path.join(templateRoot, file))) {
119
- copyItem(file);
120
- }
121
- });
122
-
123
- const items = [
124
- 'astro.config.mjs',
125
- 'tsconfig.json',
126
- 'vite.config.js',
127
- 'public',
128
- 'src',
129
- 'scripts',
130
- 'typograf-batch.js',
131
- 'resize-all.cjs',
132
- 'README.md',
133
- 'LICENSE'
134
- ];
135
- items.forEach(copyItem);
136
-
137
- const repoUrl = await getRepoUrl(targetDir, repoOption);
138
- updateReadme(targetDir, repoUrl);
139
-
140
- // Create essential config files
141
- const gitignoreContent = `
142
- # Dependencies
143
- node_modules/
144
- .pnpm-debug.log*
145
-
146
- # Environment
147
- .env
148
- .env.local
149
- .env.production
150
-
151
- # Build outputs
152
- dist/
153
- .astro/
154
-
155
- # Generated files
156
- .DS_Store
157
- .vscode/settings.json
158
-
159
- # Cache
160
- .typograf-cache.json
161
- `;
162
-
163
- const prettierrcContent = `{
164
- "semi": true,
165
- "singleQuote": true,
166
- "tabWidth": 2,
167
- "trailingComma": "es5",
168
- "printWidth": 100,
169
- "plugins": ["prettier-plugin-tailwindcss"]
170
- }
171
- `;
172
-
173
- writeFileSync(path.join(targetDir, '.gitignore'), gitignoreContent.trim());
174
- console.log('Created .gitignore');
175
-
176
- writeFileSync(path.join(targetDir, '.prettierrc'), prettierrcContent);
177
- console.log('Created .prettierrc');
178
-
179
- execSync('npm install', { cwd: targetDir, stdio: 'inherit' });
180
- updateConfig(targetDir, lang, repoUrl);
181
- }
182
-
183
- // Если скрипт запускается напрямую
184
- if (import.meta.url === `file://${process.argv[1]}`) {
185
- const args = process.argv.slice(2);
186
- let targetName;
187
- let lang;
188
- let repo;
189
- for (let i = 0; i < args.length; i++) {
190
- if (args[i] === '--lang' && i + 1 < args.length) {
191
- lang = args[i + 1];
192
- i++;
193
- } else if (args[i] === '--repo' && i + 1 < args.length) {
194
- repo = args[i + 1];
195
- i++;
196
- } else {
197
- targetName = args[i];
198
- }
199
- }
200
- await init(targetName, lang, repo);
201
- }
Binary file
Binary file
Binary file
package/resize-all.cjs DELETED
@@ -1,29 +0,0 @@
1
- // resize-all.js
2
- const fs = require('fs');
3
- const path = require('path');
4
- const sharp = require('sharp');
5
-
6
- // Какие размеры тебе нужны
7
- const sizes = [400, 800, 1200];
8
-
9
- const inputDir = './public'; // свои пути
10
- const outputDir = './public';
11
-
12
- // Перебираем все файлы в исходной папке
13
- fs.readdirSync(inputDir).forEach(file => {
14
- const ext = path.extname(file);
15
- const base = path.basename(file, ext);
16
- if (!['.jpg', '.jpeg', '.png', '.webp'].includes(ext.toLowerCase())) return;
17
-
18
- sizes.forEach(width => {
19
- sharp(path.join(inputDir, file))
20
- .resize(width)
21
- .toFile(path.join(outputDir, `${base}-${width}${ext}`), (err) => {
22
- if (err) console.error(`Ошибка на ${base}-${width}${ext}:`, err);
23
- else console.log(`Сделан: ${base}-${width}${ext}`);
24
- });
25
- });
26
-
27
- // Копируем оригинал тоже (максимальный)
28
- fs.copyFileSync(path.join(inputDir, file), path.join(outputDir, `${base}${ext}`));
29
- });
package/src/i18n/de.json DELETED
@@ -1,126 +0,0 @@
1
- {
2
- "buttons": {
3
- "share": "Teilen",
4
- "subscribe": "Abonnieren",
5
- "moreAboutProduct": "Mehr über das Produkt",
6
- "copied": "Kopiert!",
7
- "copyLink": "Link kopieren",
8
- "copyLinkToArticle": "Link zum Artikel kopieren",
9
- "morePosts": "Weitere Artikel"
10
- },
11
- "form": {
12
- "emailPlaceholder": "E-Mail",
13
- "emailLabel": "E-Mail",
14
- "subscribeAriaLabel": "Abonnement-Formular"
15
- },
16
-
17
- "nav": {
18
- "blog": "Blog",
19
- "products": "Produkte",
20
- "projects": "Fälle",
21
- "authors": "Autoren",
22
- "tags": "Kategorien",
23
- "openMenu": "Menü öffnen",
24
- "closeMenu": "Menü schließen"
25
- },
26
- "pages": {
27
- "authors": {
28
- "title": "Autoren",
29
- "description": "Lernen Sie unser Expertenteam kennen, das für {brand} schreibt",
30
- "goToAuthor": "Zum Autor gehen",
31
- "avatarAlt": "Avatar",
32
- "onPlatform": "auf"
33
- },
34
- "tags": {
35
- "title": "Kategorien",
36
- "description": "Alle Artikel nach Kategorie",
37
- "blogRubrics": "Blog-Kategorien"
38
- },
39
- "index": {
40
- "title": "<Blog>",
41
- "description": "Blog über Automatisierung aus Sicht der KI",
42
- "articles": "Artikel",
43
- "minutes": "Min"
44
- },
45
- "products": {
46
- "title": "Produkte",
47
- "description": "Alle Maugli-Produkte"
48
- },
49
- "projects": {
50
- "tagTitle": "Services nach Tag",
51
- "title": "Services"
52
- },
53
- "blog": {
54
- "moreByTag": "Mehr zum Thema"
55
- },
56
- "productsId": {
57
- "articlesByTag": "Artikel zum Thema",
58
- "casesByTag": "Fälle zum Thema"
59
- }
60
- },
61
- "socials": {
62
- "email": "E-Mail",
63
- "linkedin": "LinkedIn",
64
- "twitter": "Twitter",
65
- "telegram": "Telegram",
66
- "reddit": "Reddit",
67
- "medium": "Medium",
68
- "mastodon": "Mastodon",
69
- "bluesky": "Bluesky"
70
- },
71
- "footer": {
72
- "allRightsReserved": "Alle Rechte vorbehalten"
73
- },
74
- "shareIconAriaLabel": {
75
- "twitter": "Auf Twitter teilen",
76
- "copy": "Link kopieren",
77
- "telegram": "Auf Telegram teilen",
78
- "linkedin": "Auf LinkedIn teilen",
79
- "whatsapp": "Auf WhatsApp teilen",
80
- "facebook": "Auf Facebook teilen",
81
- "copied": "Link kopiert"
82
- },
83
- "date": {
84
- "today": "heute",
85
- "yesterday": "gestern"
86
- },
87
- "sidebarAriaLabel": "Seitenleiste",
88
- "summaryFAQCard": {
89
- "ariaLabel": "Zusammenfassung und FAQ",
90
- "summaryLabel": "Zusammenfassung:",
91
- "faqLabel": "FAQ:"
92
- },
93
- "tableOfContents": {
94
- "title": "Inhalt",
95
- "ariaLabel": "Inhalt"
96
- },
97
- "tagPill": {
98
- "ariaLabel": "Tag: {tag}"
99
- },
100
- "tagPills": {
101
- "ariaLabel": "Tag: {name} ({count})"
102
- },
103
- "tagsSection": {
104
- "allCases": "Alle Fälle",
105
- "allArticles": "Alle Artikel",
106
- "allTags": "Alle Tags",
107
- "rubricAlt": "Kategorie",
108
- "tagAriaLabel": "Tag: {name} ({count})"
109
- },
110
- "themeToggle": {
111
- "ariaLabel": "Farbschema wechseln"
112
- },
113
- "pagination": {
114
- "goToPage": "Gehe zu Seite {page} von {lastPage}",
115
- "pageOf": "Seite {currentPage} von {lastPage}"
116
- },
117
- "subscribe": {
118
- "heading": "Abonniere für Updates",
119
- "mutedText": "Erhalte die neuesten Artikel und Nachrichten zuerst!"
120
- },
121
- "notFound": {
122
- "title": "Seite nicht gefunden",
123
- "description": "Entschuldigung, diese Seite existiert nicht oder wurde entfernt.",
124
- "button": "Zur Hauptseite"
125
- }
126
- }
package/src/i18n/en.json DELETED
@@ -1,126 +0,0 @@
1
- {
2
- "buttons": {
3
- "share": "Share",
4
- "subscribe": "Subscribe",
5
- "moreAboutProduct": "More about the product",
6
- "copied": "Copied!",
7
- "copyLink": "Copy link",
8
- "copyLinkToArticle": "Copy link to article",
9
- "morePosts": "More posts"
10
- },
11
- "form": {
12
- "emailPlaceholder": "email",
13
- "emailLabel": "Email",
14
- "subscribeAriaLabel": "Subscription form"
15
- },
16
-
17
- "nav": {
18
- "blog": "Blog",
19
- "products": "Products",
20
- "projects": "Cases",
21
- "authors": "Authors",
22
- "tags": "Topics",
23
- "openMenu": "Open menu",
24
- "closeMenu": "Close menu"
25
- },
26
- "pages": {
27
- "authors": {
28
- "title": "Authors",
29
- "description": "Meet our team of experts writing for {brand}",
30
- "goToAuthor": "Go to author",
31
- "avatarAlt": "Avatar",
32
- "onPlatform": "on"
33
- },
34
- "tags": {
35
- "title": "Categories",
36
- "description": "All articles by category",
37
- "blogRubrics": "Blog categories"
38
- },
39
- "index": {
40
- "title": "<Blog>",
41
- "description": "Blog about automation through AI's eyes",
42
- "articles": "Articles",
43
- "minutes": "min"
44
- },
45
- "products": {
46
- "title": "Products",
47
- "description": "All Maugli products"
48
- },
49
- "projects": {
50
- "tagTitle": "Services by tag",
51
- "title": "Services"
52
- },
53
- "blog": {
54
- "moreByTag": "More on the topic"
55
- },
56
- "productsId": {
57
- "articlesByTag": "Articles on the topic",
58
- "casesByTag": "Cases on the topic"
59
- }
60
- },
61
- "socials": {
62
- "email": "email",
63
- "linkedin": "LinkedIn",
64
- "twitter": "Twitter",
65
- "telegram": "Telegram",
66
- "reddit": "Reddit",
67
- "medium": "Medium",
68
- "mastodon": "Mastodon",
69
- "bluesky": "Bluesky"
70
- },
71
- "footer": {
72
- "allRightsReserved": "All rights reserved"
73
- },
74
- "shareIconAriaLabel": {
75
- "twitter": "Share on Twitter",
76
- "copy": "Copy link",
77
- "telegram": "Share on Telegram",
78
- "linkedin": "Share on LinkedIn",
79
- "whatsapp": "Share on WhatsApp",
80
- "facebook": "Share on Facebook",
81
- "copied": "Link copied"
82
- },
83
- "date": {
84
- "today": "today",
85
- "yesterday": "yesterday"
86
- },
87
- "sidebarAriaLabel": "Sidebar",
88
- "summaryFAQCard": {
89
- "ariaLabel": "Summary and FAQ",
90
- "summaryLabel": "Summary:",
91
- "faqLabel": "FAQ:"
92
- },
93
- "tableOfContents": {
94
- "title": "Contents",
95
- "ariaLabel": "Contents"
96
- },
97
- "tagPill": {
98
- "ariaLabel": "Tag: {tag}"
99
- },
100
- "tagPills": {
101
- "ariaLabel": "Tag: {name} ({count})"
102
- },
103
- "tagsSection": {
104
- "allCases": "All cases",
105
- "allArticles": "All articles",
106
- "allTags": "All tags",
107
- "rubricAlt": "Category",
108
- "tagAriaLabel": "Tag: {name} ({count})"
109
- },
110
- "themeToggle": {
111
- "ariaLabel": "Change color scheme"
112
- },
113
- "pagination": {
114
- "goToPage": "Go to page {page} of {lastPage}",
115
- "pageOf": "Page {currentPage} of {lastPage}"
116
- },
117
- "subscribe": {
118
- "heading": "Subscribe for updates",
119
- "mutedText": "Get the latest articles and news first!"
120
- },
121
- "notFound": {
122
- "title": "Page not found",
123
- "description": "Sorry, this page does not exist or has been removed.",
124
- "button": "Go to main page"
125
- }
126
- }