@sugarat/theme 0.1.40 → 0.1.42
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.
- package/node.d.ts +20 -4
- package/node.js +52 -13
- package/package.json +3 -3
- package/src/composables/config/blog.ts +1 -1
- package/src/composables/config/index.ts +20 -4
- package/src/utils/node/genFeed.ts +53 -12
- package/src/utils/node/mdPlugins.ts +15 -0
- package/src/utils/node/theme.ts +13 -4
package/node.d.ts
CHANGED
|
@@ -260,22 +260,38 @@ declare namespace Theme {
|
|
|
260
260
|
*/
|
|
261
261
|
RSS?: RSSOptions;
|
|
262
262
|
}
|
|
263
|
-
type RSSOptions = FeedOptions & {
|
|
263
|
+
type RSSOptions = Omit<FeedOptions, 'id'> & {
|
|
264
|
+
id?: string;
|
|
265
|
+
/**
|
|
266
|
+
* 你的站点地址
|
|
267
|
+
* @example 'https://sugarat.top'
|
|
268
|
+
*/
|
|
264
269
|
baseUrl: string;
|
|
265
270
|
/**
|
|
266
271
|
* 线上访问的RSS地址
|
|
272
|
+
* @default
|
|
273
|
+
* @example https://sugarat.top/feed.rss
|
|
274
|
+
* ```ts
|
|
275
|
+
* `${baseUrl + VPConfig.site.base + (filename || 'feed.rss'}`
|
|
276
|
+
* ```
|
|
267
277
|
*/
|
|
268
|
-
url
|
|
278
|
+
url?: string;
|
|
269
279
|
/**
|
|
270
280
|
* 输出的RSS文件名
|
|
271
281
|
* @default 'feed.rss'
|
|
272
282
|
*/
|
|
273
283
|
filename?: string;
|
|
274
284
|
/**
|
|
275
|
-
*
|
|
285
|
+
* RSS的图标展示
|
|
276
286
|
* @default true
|
|
277
287
|
*/
|
|
278
|
-
|
|
288
|
+
icon?: boolean;
|
|
289
|
+
/**
|
|
290
|
+
* 限制输出文件包含的文章数量
|
|
291
|
+
* @default 0
|
|
292
|
+
* @description (0 不限制;> 1 会按照日期排序对输出内容进行调整)
|
|
293
|
+
*/
|
|
294
|
+
limit?: number;
|
|
279
295
|
};
|
|
280
296
|
interface Config extends DefaultTheme.Config {
|
|
281
297
|
blog?: BlogConfig;
|
package/node.js
CHANGED
|
@@ -352,6 +352,11 @@ function supportRunExtendsPlugin(config) {
|
|
|
352
352
|
markdownExtendsConfigOriginal?.(...rest);
|
|
353
353
|
};
|
|
354
354
|
}
|
|
355
|
+
const inlineConfig = config.extends;
|
|
356
|
+
if (inlineConfig.themeConfig?.blog?.RSS && inlineConfig.themeConfig?.blog?.RSS?.icon !== false && inlineConfig.themeConfig?.socialLinks?.length && !inlineConfig.themeConfig?.socialLinks?.[0].link) {
|
|
357
|
+
const { RSS } = inlineConfig.themeConfig?.blog;
|
|
358
|
+
inlineConfig.themeConfig.socialLinks[0].link = `${RSS.baseUrl}${(config.base || "/") + (RSS.filename || "feed.rss")}`;
|
|
359
|
+
}
|
|
355
360
|
}
|
|
356
361
|
|
|
357
362
|
// src/utils/node/theme.ts
|
|
@@ -369,6 +374,7 @@ function patchDefaultThemeSideBar(cfg) {
|
|
|
369
374
|
]
|
|
370
375
|
} : void 0;
|
|
371
376
|
}
|
|
377
|
+
var pageMap = /* @__PURE__ */ new Map();
|
|
372
378
|
function getArticles(cfg) {
|
|
373
379
|
const srcDir = cfg?.srcDir || process.argv.slice(2)?.[1] || ".";
|
|
374
380
|
const files = import_fast_glob.default.sync(`${srcDir}/**/*.md`, { ignore: ["node_modules"] });
|
|
@@ -389,9 +395,13 @@ function getArticles(cfg) {
|
|
|
389
395
|
""
|
|
390
396
|
);
|
|
391
397
|
}
|
|
398
|
+
pageMap.set(`/${route}`, v);
|
|
392
399
|
const fileContent = import_fs.default.readFileSync(v, "utf-8");
|
|
400
|
+
const { data: frontmatter, excerpt } = (0, import_gray_matter.default)(fileContent, {
|
|
401
|
+
excerpt: true
|
|
402
|
+
});
|
|
393
403
|
const meta = {
|
|
394
|
-
...
|
|
404
|
+
...frontmatter
|
|
395
405
|
};
|
|
396
406
|
if (!meta.title) {
|
|
397
407
|
meta.title = getDefaultTitle(fileContent);
|
|
@@ -425,13 +435,13 @@ function getArticles(cfg) {
|
|
|
425
435
|
}
|
|
426
436
|
function patchVPThemeConfig(cfg, vpThemeConfig = {}) {
|
|
427
437
|
const RSS = cfg?.RSS;
|
|
428
|
-
if (RSS && RSS.
|
|
438
|
+
if (RSS && RSS.icon !== false) {
|
|
429
439
|
vpThemeConfig.socialLinks = [
|
|
430
440
|
{
|
|
431
441
|
icon: {
|
|
432
442
|
svg: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><path d="M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48s48 21.49 48 48s-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634c-5.214-80.05-69.243-143.92-149.123-149.123c-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425c110.546 5.974 198.997 94.536 204.964 204.964c.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038c-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432c167.83 6.025 302.21 141.191 308.205 308.205c.232 6.449-4.978 11.787-11.432 11.787z" fill="currentColor"></path></svg>'
|
|
433
443
|
},
|
|
434
|
-
link: RSS
|
|
444
|
+
link: RSS?.url
|
|
435
445
|
}
|
|
436
446
|
];
|
|
437
447
|
}
|
|
@@ -445,34 +455,58 @@ var import_child_process2 = require("child_process");
|
|
|
445
455
|
|
|
446
456
|
// src/utils/node/genFeed.ts
|
|
447
457
|
var import_path2 = __toESM(require("path"));
|
|
448
|
-
var import_fs2 = require("fs");
|
|
458
|
+
var import_fs2 = __toESM(require("fs"));
|
|
449
459
|
var import_feed = require("feed");
|
|
450
|
-
function genFeed(config) {
|
|
460
|
+
async function genFeed(config) {
|
|
451
461
|
const blogCfg = config.userConfig.themeConfig.blog;
|
|
452
|
-
|
|
462
|
+
let posts = blogCfg.pagesData;
|
|
453
463
|
const { RSS, authorList = [] } = blogCfg;
|
|
454
464
|
if (!RSS)
|
|
455
465
|
return;
|
|
466
|
+
const { createMarkdownRenderer } = await import("vitepress");
|
|
467
|
+
const mdRender = await createMarkdownRenderer(
|
|
468
|
+
config.srcDir,
|
|
469
|
+
config.markdown,
|
|
470
|
+
config.site.base,
|
|
471
|
+
config.logger
|
|
472
|
+
);
|
|
456
473
|
console.log();
|
|
457
474
|
console.log("=== feed: https://github.com/jpmonette/feed ===");
|
|
458
475
|
const { base } = config.userConfig;
|
|
459
476
|
const { baseUrl, filename } = RSS;
|
|
460
|
-
const feed = new import_feed.Feed(
|
|
477
|
+
const feed = new import_feed.Feed({
|
|
478
|
+
id: baseUrl,
|
|
479
|
+
link: baseUrl,
|
|
480
|
+
...RSS
|
|
481
|
+
});
|
|
461
482
|
posts.sort(
|
|
462
483
|
(a, b) => +new Date(b.meta.date) - +new Date(a.meta.date)
|
|
463
484
|
);
|
|
485
|
+
posts = posts.filter((v) => v.meta.layout !== "home").filter((v) => v.meta.hidden !== true);
|
|
486
|
+
if (void 0 !== RSS?.limit && RSS?.limit > 0) {
|
|
487
|
+
posts.splice(RSS.limit);
|
|
488
|
+
}
|
|
464
489
|
for (const { route, meta } of posts) {
|
|
465
|
-
const { title, description, date
|
|
466
|
-
if (hidden)
|
|
467
|
-
continue;
|
|
490
|
+
const { title, description, date } = meta;
|
|
468
491
|
const author = meta.author ?? blogCfg.author;
|
|
469
|
-
|
|
492
|
+
let link = `${baseUrl}${withBase(
|
|
493
|
+
base || "",
|
|
494
|
+
route.replace(/(^|\/)index$/, "$1")
|
|
495
|
+
)}`;
|
|
496
|
+
link = link.endsWith("/") ? link : `${link}${config?.cleanUrls ? "" : ".html"}`;
|
|
470
497
|
const authorLink = authorList.find((v) => v.nickname === author)?.url;
|
|
498
|
+
let html;
|
|
499
|
+
const filepath = pageMap.get(route);
|
|
500
|
+
if (filepath) {
|
|
501
|
+
const fileContent = import_fs2.default.readFileSync(filepath, "utf-8");
|
|
502
|
+
html = mdRender.render(fileContent);
|
|
503
|
+
}
|
|
471
504
|
feed.addItem({
|
|
472
505
|
title,
|
|
473
506
|
id: link,
|
|
474
507
|
link,
|
|
475
508
|
description,
|
|
509
|
+
content: html,
|
|
476
510
|
author: [
|
|
477
511
|
{
|
|
478
512
|
name: author,
|
|
@@ -482,9 +516,14 @@ function genFeed(config) {
|
|
|
482
516
|
date: new Date(date)
|
|
483
517
|
});
|
|
484
518
|
}
|
|
485
|
-
const
|
|
519
|
+
const RSSFilename = filename || "feed.rss";
|
|
520
|
+
const RSSFile = import_path2.default.join(config.outDir, RSSFilename);
|
|
486
521
|
(0, import_fs2.writeFileSync)(RSSFile, feed.rss2());
|
|
487
|
-
console.log("\u{1F389} RSS generated",
|
|
522
|
+
console.log("\u{1F389} RSS generated", RSSFilename);
|
|
523
|
+
console.log("rss filepath:", RSSFile);
|
|
524
|
+
console.log("rss url:", `${baseUrl}${config.site.base + RSSFilename}`);
|
|
525
|
+
console.log("include", posts.length, "posts");
|
|
526
|
+
console.log();
|
|
488
527
|
console.log();
|
|
489
528
|
}
|
|
490
529
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.42",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"scripts": {
|
|
59
59
|
"dev": "npm run build:node && npm run dev:docs",
|
|
60
60
|
"dev:docs": "vitepress dev docs",
|
|
61
|
-
"dev:node": "npx tsup src/node.ts --dts --out-dir=./ --watch",
|
|
61
|
+
"dev:node": "npx tsup src/node.ts --dts --out-dir=./ --watch --external vitepress",
|
|
62
62
|
"build": "npm run build:node && npm run build:docs",
|
|
63
63
|
"build:docs": "vitepress build docs",
|
|
64
|
-
"build:node": "npx tsup src/node.ts --dts --out-dir=./",
|
|
64
|
+
"build:node": "npx tsup src/node.ts --dts --out-dir=./ --external vitepress",
|
|
65
65
|
"serve": "vitepress serve docs"
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -141,7 +141,7 @@ export function useActiveAnchor() {
|
|
|
141
141
|
onMounted(() => {
|
|
142
142
|
const { hash } = window.location
|
|
143
143
|
if (hash) {
|
|
144
|
-
el.value = document.querySelector(decodeURIComponent(hash))
|
|
144
|
+
el.value = document.querySelector(decodeURIComponent(hash)) as any
|
|
145
145
|
}
|
|
146
146
|
})
|
|
147
147
|
return el
|
|
@@ -281,22 +281,38 @@ export namespace Theme {
|
|
|
281
281
|
RSS?: RSSOptions
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
export type RSSOptions = FeedOptions & {
|
|
284
|
+
export type RSSOptions = Omit<FeedOptions, 'id'> & {
|
|
285
|
+
id?: string
|
|
286
|
+
/**
|
|
287
|
+
* 你的站点地址
|
|
288
|
+
* @example 'https://sugarat.top'
|
|
289
|
+
*/
|
|
285
290
|
baseUrl: string
|
|
286
291
|
/**
|
|
287
292
|
* 线上访问的RSS地址
|
|
293
|
+
* @default
|
|
294
|
+
* @example https://sugarat.top/feed.rss
|
|
295
|
+
* ```ts
|
|
296
|
+
* `${baseUrl + VPConfig.site.base + (filename || 'feed.rss'}`
|
|
297
|
+
* ```
|
|
288
298
|
*/
|
|
289
|
-
url
|
|
299
|
+
url?: string
|
|
290
300
|
/**
|
|
291
301
|
* 输出的RSS文件名
|
|
292
302
|
* @default 'feed.rss'
|
|
293
303
|
*/
|
|
294
304
|
filename?: string
|
|
295
305
|
/**
|
|
296
|
-
*
|
|
306
|
+
* RSS的图标展示
|
|
297
307
|
* @default true
|
|
298
308
|
*/
|
|
299
|
-
|
|
309
|
+
icon?: boolean
|
|
310
|
+
/**
|
|
311
|
+
* 限制输出文件包含的文章数量
|
|
312
|
+
* @default 0
|
|
313
|
+
* @description (0 不限制;> 1 会按照日期排序对输出内容进行调整)
|
|
314
|
+
*/
|
|
315
|
+
limit?: number
|
|
300
316
|
}
|
|
301
317
|
export interface Config extends DefaultTheme.Config {
|
|
302
318
|
blog?: BlogConfig
|
|
@@ -1,42 +1,78 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import path from 'path'
|
|
3
|
-
import { writeFileSync } from 'fs'
|
|
3
|
+
import fs, { writeFileSync } from 'fs'
|
|
4
4
|
import { Feed } from 'feed'
|
|
5
5
|
import type { SiteConfig } from 'vitepress'
|
|
6
6
|
import type { Theme } from '../../composables/config/index'
|
|
7
7
|
import { withBase } from './index'
|
|
8
|
+
import { pageMap } from './theme'
|
|
8
9
|
|
|
9
|
-
export function genFeed(config: SiteConfig) {
|
|
10
|
+
export async function genFeed(config: SiteConfig) {
|
|
10
11
|
const blogCfg: Theme.BlogConfig = config.userConfig.themeConfig.blog
|
|
11
|
-
|
|
12
|
+
let posts: Theme.PageData[] = blogCfg.pagesData
|
|
12
13
|
const { RSS, authorList = [] } = blogCfg
|
|
13
14
|
if (!RSS) return
|
|
15
|
+
const { createMarkdownRenderer } = await import('vitepress')
|
|
16
|
+
|
|
17
|
+
const mdRender = await createMarkdownRenderer(
|
|
18
|
+
config.srcDir,
|
|
19
|
+
config.markdown,
|
|
20
|
+
config.site.base,
|
|
21
|
+
config.logger
|
|
22
|
+
)
|
|
14
23
|
console.log()
|
|
15
24
|
console.log('=== feed: https://github.com/jpmonette/feed ===')
|
|
16
25
|
const { base } = config.userConfig
|
|
17
26
|
|
|
18
27
|
const { baseUrl, filename } = RSS
|
|
19
|
-
const feed = new Feed(
|
|
28
|
+
const feed = new Feed({
|
|
29
|
+
id: baseUrl,
|
|
30
|
+
link: baseUrl,
|
|
31
|
+
...RSS
|
|
32
|
+
})
|
|
20
33
|
|
|
21
34
|
posts.sort(
|
|
22
35
|
(a, b) =>
|
|
23
36
|
+new Date(b.meta.date as string) - +new Date(a.meta.date as string)
|
|
24
37
|
)
|
|
25
38
|
|
|
39
|
+
posts = posts
|
|
40
|
+
// 过滤掉 layout:home
|
|
41
|
+
.filter((v) => v.meta.layout !== 'home')
|
|
42
|
+
// 过滤掉不展示的
|
|
43
|
+
.filter((v) => v.meta.hidden !== true)
|
|
44
|
+
|
|
45
|
+
if (undefined !== RSS?.limit && RSS?.limit > 0) {
|
|
46
|
+
posts.splice(RSS.limit)
|
|
47
|
+
}
|
|
48
|
+
|
|
26
49
|
for (const { route, meta } of posts) {
|
|
27
|
-
const { title, description, date
|
|
28
|
-
|
|
50
|
+
const { title, description, date } = meta
|
|
51
|
+
|
|
29
52
|
const author = meta.author ?? blogCfg.author
|
|
30
|
-
|
|
53
|
+
let link = `${baseUrl}${withBase(
|
|
54
|
+
base || '',
|
|
55
|
+
// 移除末尾的index
|
|
56
|
+
route.replace(/(^|\/)index$/, '$1')
|
|
57
|
+
)}`
|
|
58
|
+
// 补全后缀
|
|
59
|
+
link = link.endsWith('/')
|
|
60
|
+
? link
|
|
61
|
+
: `${link}${config?.cleanUrls ? '' : '.html'}`
|
|
31
62
|
const authorLink = authorList.find((v) => v.nickname === author)?.url
|
|
63
|
+
let html
|
|
64
|
+
const filepath = pageMap.get(route)
|
|
65
|
+
if (filepath) {
|
|
66
|
+
const fileContent = fs.readFileSync(filepath, 'utf-8')
|
|
67
|
+
html = mdRender.render(fileContent)
|
|
68
|
+
}
|
|
69
|
+
|
|
32
70
|
feed.addItem({
|
|
33
71
|
title,
|
|
34
72
|
id: link,
|
|
35
|
-
// TODO: 待定,添加transform
|
|
36
73
|
link,
|
|
37
74
|
description,
|
|
38
|
-
|
|
39
|
-
// content: html,
|
|
75
|
+
content: html,
|
|
40
76
|
author: [
|
|
41
77
|
{
|
|
42
78
|
name: author,
|
|
@@ -46,8 +82,13 @@ export function genFeed(config: SiteConfig) {
|
|
|
46
82
|
date: new Date(date)
|
|
47
83
|
})
|
|
48
84
|
}
|
|
49
|
-
const
|
|
85
|
+
const RSSFilename = filename || 'feed.rss'
|
|
86
|
+
const RSSFile = path.join(config.outDir, RSSFilename)
|
|
50
87
|
writeFileSync(RSSFile, feed.rss2())
|
|
51
|
-
console.log('🎉 RSS generated',
|
|
88
|
+
console.log('🎉 RSS generated', RSSFilename)
|
|
89
|
+
console.log('rss filepath:', RSSFile)
|
|
90
|
+
console.log('rss url:', `${baseUrl}${config.site.base + RSSFilename}`)
|
|
91
|
+
console.log('include', posts.length, 'posts')
|
|
92
|
+
console.log()
|
|
52
93
|
console.log()
|
|
53
94
|
}
|
|
@@ -92,4 +92,19 @@ export function supportRunExtendsPlugin(config: UserConfig<Theme.Config>) {
|
|
|
92
92
|
markdownExtendsConfigOriginal?.(...rest)
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
|
|
96
|
+
// 特殊处理RSS,自动生成url(未来统一维护到 RSS插件里,待下一版主题架构升级)
|
|
97
|
+
const inlineConfig = config.extends as UserConfig<Theme.Config>
|
|
98
|
+
|
|
99
|
+
if (
|
|
100
|
+
inlineConfig.themeConfig?.blog?.RSS &&
|
|
101
|
+
inlineConfig.themeConfig?.blog?.RSS?.icon !== false &&
|
|
102
|
+
inlineConfig.themeConfig?.socialLinks?.length &&
|
|
103
|
+
!inlineConfig.themeConfig?.socialLinks?.[0].link
|
|
104
|
+
) {
|
|
105
|
+
const { RSS } = inlineConfig.themeConfig?.blog
|
|
106
|
+
inlineConfig.themeConfig.socialLinks[0].link = `${RSS.baseUrl}${
|
|
107
|
+
(config.base || '/') + (RSS.filename || 'feed.rss')
|
|
108
|
+
}`
|
|
109
|
+
}
|
|
95
110
|
}
|
package/src/utils/node/theme.ts
CHANGED
|
@@ -20,6 +20,9 @@ export function patchDefaultThemeSideBar(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
20
20
|
: undefined
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// hack:RSS用
|
|
24
|
+
export const pageMap = new Map<string, string>()
|
|
25
|
+
|
|
23
26
|
export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
24
27
|
const srcDir = cfg?.srcDir || process.argv.slice(2)?.[1] || '.'
|
|
25
28
|
const files = glob.sync(`${srcDir}/**/*.md`, { ignore: ['node_modules'] })
|
|
@@ -51,11 +54,17 @@ export function getArticles(cfg?: Partial<Theme.BlogConfig>) {
|
|
|
51
54
|
''
|
|
52
55
|
)
|
|
53
56
|
}
|
|
57
|
+
// hack:RSS使用
|
|
58
|
+
pageMap.set(`/${route}`, v)
|
|
54
59
|
|
|
55
60
|
const fileContent = fs.readFileSync(v, 'utf-8')
|
|
61
|
+
// TODO:摘要生成优化
|
|
62
|
+
const { data: frontmatter, excerpt } = matter(fileContent, {
|
|
63
|
+
excerpt: true
|
|
64
|
+
})
|
|
56
65
|
|
|
57
66
|
const meta: Partial<Theme.PageMeta> = {
|
|
58
|
-
...
|
|
67
|
+
...frontmatter
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
if (!meta.title) {
|
|
@@ -118,15 +127,15 @@ export function patchVPThemeConfig(
|
|
|
118
127
|
cfg?: Partial<Theme.BlogConfig>,
|
|
119
128
|
vpThemeConfig: any = {}
|
|
120
129
|
) {
|
|
121
|
-
// 添加 icon
|
|
130
|
+
// 添加 RSS icon
|
|
122
131
|
const RSS = cfg?.RSS
|
|
123
|
-
if (RSS && RSS.
|
|
132
|
+
if (RSS && RSS.icon !== false) {
|
|
124
133
|
vpThemeConfig.socialLinks = [
|
|
125
134
|
{
|
|
126
135
|
icon: {
|
|
127
136
|
svg: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><path d="M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48s48 21.49 48 48s-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634c-5.214-80.05-69.243-143.92-149.123-149.123c-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425c110.546 5.974 198.997 94.536 204.964 204.964c.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038c-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432c167.83 6.025 302.21 141.191 308.205 308.205c.232 6.449-4.978 11.787-11.432 11.787z" fill="currentColor"></path></svg>'
|
|
128
137
|
},
|
|
129
|
-
link: RSS
|
|
138
|
+
link: RSS?.url
|
|
130
139
|
}
|
|
131
140
|
]
|
|
132
141
|
}
|