From 16e2a3fd905c5ffb5e0a90c1a4805559d372b389 Mon Sep 17 00:00:00 2001 From: yingyu5658 Date: Sun, 11 Jan 2026 22:59:03 +0800 Subject: docs: post weekly --- content/mastodon.md | 9 + content/posts/weekly/5.md | 112 +++++ layouts/partials/custom_head.html | 6 + layouts/partials/style.html | 18 +- layouts/shortcodes/mastodon.html | 16 + static/css/mastodon-timeline.min.css | 650 ++++++++++++++++++++++++ static/js/mastodon-timeline.esm.js | 949 +++++++++++++++++++++++++++++++++++ 7 files changed, 1752 insertions(+), 8 deletions(-) create mode 100644 content/mastodon.md create mode 100644 content/posts/weekly/5.md create mode 100644 layouts/shortcodes/mastodon.html create mode 100644 static/css/mastodon-timeline.min.css create mode 100644 static/js/mastodon-timeline.esm.js diff --git a/content/mastodon.md b/content/mastodon.md new file mode 100644 index 0000000..9431934 --- /dev/null +++ b/content/mastodon.md @@ -0,0 +1,9 @@ +--- +title: 'Mastodon' +date: '2026-01-11T20:09:03+08:00' +slug: +categories: +tags: +comments: false +--- +{{< mastodon >}} diff --git a/content/posts/weekly/5.md b/content/posts/weekly/5.md new file mode 100644 index 0000000..204770e --- /dev/null +++ b/content/posts/weekly/5.md @@ -0,0 +1,112 @@ +--- +date: '2026-01-11T17:52:03+08:00' +title: '回声周刊 Vol.5:「相关」和「有关」的滥用' +categories: + - 回声周刊 +issue: 5 +tags: + - 语言 + - 中文 + - 西西弗 + - 村上春树 +draft: false +--- + +![](https://images.glowisle.me/) + +> 这里是回声周刊,分享我这周读过的文章书籍、近期发生的大事小事。每周日更新。如果你对这个周刊感兴趣,可以 [订阅周刊](/categories/%E5%9B%9E%E5%A3%B0%E5%91%A8%E5%88%8A/atom.xml) 或加入 [TG频道](https://t.me/glowisle)。 + +这周我一直在忙期末复习,因此本期周刊内容很少,最晚可能要到下下期恢复正常量。 + +## 〰︎ 声波 + +{{< music + cover="https://images.glowisle.me/b67616d00001e0274c732f8aa0e0ccbb3d17d96.jpeg" + title="From The Start" + artist="" + apple="" + netease="" + spotify="https://open.spotify.com/track/43iIQbw5hx986dUEZbr3eN?si=4c4d4d3680134d9b" +>}} + +## 🕮 声源 + +### 不要逃避解释:论「相关」和「有关」在日常写作中的滥用 + +> 🔗 [文章链接](https://hsu.cy/2025/04/irrelevancy/) + +文章指出了中文里「相关」和「有关」被滥用的现象,进行了批判,并给出了减少使用这两个词的例子。 + +文章里提到的最经典的例子「有关部门」,我觉得是刻意为之。这和「原则上不可以」就是「可以」的意味很相似,一定有人会说这是中文的博大精深,其实很多情况下就是故意含糊其辞的说法。不过这篇文章确实一针见血,能给写作者很大的启发。除了文章提到的两个词,我觉得在一些应试叙事文里「便」也被滥用了,它是「就」的书面语版本,表动作或事件之间的因果联系和连续性,也就是承接关系。我曾经读过我同学的一篇作文,事件就是买手抓饼身上没带钱,老板说没事可以不用给。他在那篇六百多字的文章里用了二三十个「便」。 + + +### 你分得清 Follow Feed 和 Subscribe 吗? + +今天在搜集RSS订阅源的时候思考了一个很常见的文件命名 —— `feed.xml`。 + +为什么在表达「RSS订阅」这个意思的时候,不用常见的subscribe(订阅),或者follow(关注),而是用feed(v. 喂养;**供应** / n. 饲料)这个奇怪的词呢? + +#### subscribe + +来看看这个词在字典中的含义: + +> to pay money to an organization in order to receive a product, use a service regularly[^1] + +**向一个组织付费以收到产品**、**使用周期性的服务**、**主动选择,直接接收更新**如 email, push notifications(消息推送)。 + +仔细一想,这是不是和**Newsletter**的模式很像?因此可以看到很多支持Newsletter的网站,会在提交邮箱的输入框旁边附上一个写着Subscribe的按钮。 + +除了Newsletter,也适用于某些软件的会员服务,例如: + +> 2.3 million people subscribe to this online music service. +> +> 230 万人订阅了这项在线音乐服务。 + +从词源学的角度看,subscribe的词根sub-(在下面)+scribe(写),原意是「在文件下方签名」。这其中包含着一种「我登记,你准时交付」的「契约感」 + +所以,遇到这种情况,使用Subscribe是最好的选择。 + +#### Follow + +这个单词多被用于社交媒体的「关注」按钮里,它的意思更多是"Publicly add someone to one's network(添加到公开网络)",以及"Show their posts up in main algorithm-dependent feed"(在关注界面,受算法影响地展示他们的帖子)。[^2] + +在我看来,这和subscribe的微妙的区别在于,subscribe的作用对象在大多数情况下是正式的、有质量保证「服务」,而follow是一种相对轻松的「帖子(post)」,聚焦在「关注个人」而非「订阅服务」。 + +#### Feed + +最后在来看这个经常被使用于RSS订阅的feed的释义: + +> to supply something to a person or thing(向某人提供某物), or put something into a machine or system, especially in a regular or continuous way(将某物放入机器 / 系统,尤其指有规律的、连续的方式). + +这不是某个动作,而是目的,这是机器对机器的自动化喂养。它的结果是:获取一个由你自己筛选的源所供给的个性化信息流。因此这个词非常贴合RSS这个模式。 + +这三个词的背后隐藏着用户主动权的变化,subscribe是一种「强主动」,点名要看,不能错过的需求;follow是像推特的关注那样「我想看,但有算法帮我推荐」的机制;feed在RSS盛行的时代也是一种用户完全掌控的强主动,但在现代APP里,又有了一层「投喂」的意思,例如TikTok和小红书的算法推荐。不得不说,「投喂」这个词实在是太难听了。 + +## ♇ 所在 + +### 以后再也不去线下店买书了 + +这周六又去了一次西西弗,不过是以前没去过的店。因为很想看《1973年的弹子球》,又等不及网购 + +举着豆瓣在书架绕了半天,那么一面墙的日本文学,有《且听风吟》,有《舞!舞!舞!》,就是没有我想要的那本。最后终于鼓起勇气跟店员说能不能帮我找一下,结果他们还没卖。 + +就拿了一本《一个人的好天气》和《舞》结账,结果花了一百五十块。唉,真黑啊! + +![价值四块钱的袋子……](https://images.glowisle.me/https://images.glowisle.me/E4188D7B80E34C235C46CF10E0A5D4BE.jpg) + + +我不知道怎么拒绝说我自己带包了不要袋子,花四块钱又买了一个袋子,这次出行唯一成功的就是悬崖勒马没有被她忽悠充值办卡…… + +出来之后,看到有麦当劳,就进去一口气点了三个冰淇淋吃。 + +![](https://images.glowisle.me/DFE6701348DB336E54AF1C611F34719A.jpg) + +![战况](https://images.glowisle.me/230710588BD53B2E3B9C6F79E38EE7B4.jpg) + +小时候求着父母才能偶尔成到一个的东西,现在一口气吃三个,爽! + +[^1]: [SUBSCRIBE - Cambridge Dictionary](https://dictionary.cambridge.org/zhs/%E8%AF%8D%E5%85%B8/%E8%8B%B1%E8%AF%AD-%E6%B1%89%E8%AF%AD-%E7%B9%81%E4%BD%93/subscribe) + +[^2]: [In a social app, do I choose "Subscribe" or "Follow"? - Quora](https://www.quora.com/In-a-social-app-do-I-choose-Subscribe-or-Follow) + + diff --git a/layouts/partials/custom_head.html b/layouts/partials/custom_head.html index 206ee0b..a485758 100644 --- a/layouts/partials/custom_head.html +++ b/layouts/partials/custom_head.html @@ -15,3 +15,9 @@ rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> + diff --git a/layouts/partials/style.html b/layouts/partials/style.html index 50650ea..8429fdb 100644 --- a/layouts/partials/style.html +++ b/layouts/partials/style.html @@ -16,7 +16,7 @@ --code-bg-color: #f2f2f2; --code-text-color: #222; --blockquote-border-color: #666; - --blockquote-text-color: #666; + --blockquote-text-color: #8c8c8c; --upvoted-color: #fa8072; --caption-text-color: #666; --toc-text-color: #e5e5e5; @@ -95,8 +95,9 @@ } article p { - line-height: 40px; + line-height: 35px; margin-top: 20px; + font-weight: 550; } .item-link { @@ -289,12 +290,17 @@ --music-bg-hover-dark: #525252; /* neutral-600 */ --music-bg-dark: rgba(82, 82, 82, 0.5); /* neutral-600/50 */ --music-text-secondary: #a3a3a3; + --color-background: var(--body-bg-color) !important; } blockquote strong { font-weight: 600; } + article p { + font-weight: 400; + } + .music-btn { background-color: var(--music-bg-dark); } @@ -526,18 +532,14 @@ } blockquote { - border-left: 4px solid var(--blockquote-border-color); + /* border-left: 4px solid var(--blockquote-border-color); */ color: var(--blockquote-text-color); margin: 0; margin-top: 17px; - padding-left: 16px; + padding-left: 20px; font-style: normal; } - blockquote p { - margin: 0; - } - footer { padding: 25px 0; text-align: left; diff --git a/layouts/shortcodes/mastodon.html b/layouts/shortcodes/mastodon.html new file mode 100644 index 0000000..cfb15ca --- /dev/null +++ b/layouts/shortcodes/mastodon.html @@ -0,0 +1,16 @@ + + + + + + diff --git a/static/css/mastodon-timeline.min.css b/static/css/mastodon-timeline.min.css new file mode 100644 index 0000000..ec8493e --- /dev/null +++ b/static/css/mastodon-timeline.min.css @@ -0,0 +1,650 @@ +.mt-container, +.mt-container[data-theme="light"], +.mt-dialog, +.mt-dialog[data-theme="light"] { + --mt-txt-max-lines: none; + --mt-preview-max-lines: none; + --mt-color-bg: #fff; + --mt-color-bg-hover: #e9eef1; + --mt-color-line-gray: #c0cdd9; + --mt-color-contrast-gray: #606984; + --mt-color-content-txt: #000; + --mt-color-hashtag: #d7e1e9; + --mt-color-link: #3a3bff; + --mt-color-error-txt: #8b0000; + --mt-color-btn-bg: #6364ff; + --mt-color-btn-bg-hover: #563acc; + --mt-color-btn-txt: #fff; + --mt-color-backdrop: #00000090; + --mt-color-placeholder: #60698425; +} +.mt-container[data-theme="dark"], +.mt-dialog[data-theme="dark"] { + --mt-color-bg: #181821; + --mt-color-bg-hover: #21232c; + --mt-color-line-gray: #393f4f; + --mt-color-contrast-gray: #606984; + --mt-color-content-txt: #fff; + --mt-color-hashtag: #292c38; + --mt-color-link: #8c8dff; + --mt-color-error-txt: #fe6c6c; +} +.mt-container button, +.mt-dialog button { + font: inherit; +} +.mt-container a, +.mt-container button, +.mt-dialog button { + cursor: pointer; +} +.mt-container { + display: flex; + flex-direction: column; + height: 100%; + overflow-y: auto; + position: relative; + background-color: var(--mt-color-bg); + scrollbar-color: var(--mt-color-contrast-gray) var(--mt-color-bg); + scrollbar-width: auto; + container: mt-container/inline-size; +} +.mt-container::-webkit-scrollbar { + width: 0.25rem; + height: 0.25rem; +} +.mt-container::-webkit-scrollbar-thumb { + background-color: var(--mt-color-contrast-gray); + border: none; + border-radius: 3rem; +} +.mt-container::-webkit-scrollbar-thumb:active, +.mt-container::-webkit-scrollbar-thumb:hover { + background-color: var(--mt-color-contrast-gray); +} +.mt-container::-webkit-scrollbar-track { + background-color: var(--mt-color-bg); + border: none; + border-radius: 0; +} +.mt-container::-webkit-scrollbar-corner, +.mt-container::-webkit-scrollbar-track:active, +.mt-container::-webkit-scrollbar-track:hover { + background-color: var(--mt-color-bg); +} +.mt-container a { + text-decoration: none; + color: var(--mt-color-link); +} +.mt-container a:not(.mt-post-preview):hover { + text-decoration: underline; +} +.mt-body { + padding: 1rem; + white-space: pre-wrap; + word-wrap: break-word; + margin-bottom: 1rem; +} +.mt-body .invisible { + font-size: 0; + line-height: 0; + display: inline-block; + width: 0; + height: 0; + position: absolute; +} +.mt-post { + margin: 0.25rem; + padding: 1rem 0.5rem; + position: relative; + min-height: 3.75rem; + background-color: transparent; + border-bottom: 1px solid var(--mt-color-line-gray); +} +.mt-post:focus, +.mt-post:hover { + cursor: pointer; + background-color: var(--mt-color-bg-hover); +} +.mt-container:not(:has(.mt-footer)) .mt-post:last-child { + border-bottom: none; +} +.mt-post p:last-child { + margin-bottom: 0; +} +.mt-post-avatar { + margin-right: 0.75rem; +} +.mt-post-avatar-standard { + width: 2.25rem; + height: 2.25rem; +} +.mt-post-avatar-boosted { + width: 3rem; + height: 3rem; + position: relative; +} +.mt-post-avatar-image-big img, +.mt-post-avatar-image-small img { + aspect-ratio: 1/1; + border-radius: 0.25rem; + overflow: hidden; +} +.mt-post-avatar-image-big img { + width: 2.25rem; + height: 2.25rem; +} +.mt-post-avatar-image-small img { + width: 1.5rem; + height: 1.5rem; + top: 1.5rem; + left: 1.5rem; + position: absolute; +} +.mt-post-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 1rem; +} +.mt-post-header-user { + overflow: hidden; + padding-right: 0.75rem; +} +.mt-post-header-user .mt-custom-emoji { + height: 1rem; + min-width: 1rem; + width: auto; +} +.mt-container .mt-post-header-user > a { + color: var(--mt-color-content-txt); + overflow-wrap: anywhere; +} +.mt-container .mt-post-header-user > a:hover { + text-decoration: none; +} +.mt-post-header-user-name { + font-weight: 600; +} +.mt-container .mt-post-header-user:hover .mt-post-header-user-name { + text-decoration: underline; +} +.mt-post-header-user-account { + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + color: var(--mt-color-contrast-gray); +} +.mt-post-header-date { + display: flex; + font-size: 0.75rem; + text-align: right; + margin-left: auto; +} +.mt-post-header-date .mt-post-pinned { + width: 1.25rem; + margin-top: -0.25rem; + fill: var(--mt-color-contrast-gray); +} +.mt-container .mt-post-header-date > a { + white-space: nowrap; + color: var(--mt-color-contrast-gray) !important; +} +.mt-post-txt { + margin-bottom: 1rem; + color: var(--mt-color-content-txt); +} +.mt-post-txt .spoiler-txt-hidden { + display: none; +} +.mt-post-txt.truncate { + display: -webkit-box; + overflow: hidden; + -webkit-line-clamp: var(--mt-txt-max-lines); + -webkit-box-orient: vertical; +} +.mt-post-txt:not(.truncate) .ellipsis::after { + content: "..."; +} +.mt-post-txt blockquote { + border-left: 0.25rem solid var(--mt-color-line-gray); + margin-left: 0; + padding-left: 0.5rem; +} +.mt-post-txt .mt-custom-emoji { + height: 1.5rem; + min-width: 1.5rem; + margin-bottom: -0.25rem; + width: auto; +} +.mt-post-txt .mention.hashtag { + display: inline-block; + font-size: 0.8rem; + border-radius: 0.25rem; + background-color: var(--mt-color-hashtag); + padding: 0.25rem 0.5rem; + margin: 0 0.25rem 0.25rem 0; +} +.mt-post-txt .mention.hashtag:only-child { + margin: 0; +} +.mt-post-poll { + margin-bottom: 1rem; + color: var(--mt-color-content-txt); +} +.mt-post-poll ul { + list-style: none; + padding: 0; + margin: 0; +} +.mt-post-poll ul li { + font-size: 0.9rem; + margin-bottom: 0.5rem; +} +.mt-post-poll.mt-post-poll-expired ul li { + color: var(--mt-color-contrast-gray); +} +.mt-post-poll ul li:not(:last-child) { + margin-bottom: 0.25rem; +} +.mt-post-poll ul li:before { + content: "◯"; + padding-right: 0.5rem; +} +.mt-post-poll.mt-post-poll-expired ul li:before { + content: ""; + padding-right: 0; +} +.mt-post-media-wrapper { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0.5rem; + margin-bottom: 1rem; +} +.mt-post-media { + position: relative; + overflow: hidden; + width: 100%; +} +.mt-post-media-wrapper:has(> :last-child:nth-child(odd)) + .mt-post-media:not(:only-child):first-child { + grid-column: 1/3; +} +.mt-post-media:only-child { + grid-column: 1/3; +} +.mt-post-media-spoiler > .mt-btn-play, +.mt-post-media-spoiler > audio, +.mt-post-media-spoiler > img, +.mt-post-media-spoiler > video { + filter: blur(2rem); + pointer-events: none; +} +.mt-post-media, +.mt-post-media-spoiler > audio, +.mt-post-media-spoiler > img, +.mt-post-media > img, +.mt-post-media > video { + border-radius: 0.5rem; +} +.mt-post-media > audio { + width: 100%; + position: relative; + z-index: 1; +} +.mt-post-media > img, +.mt-post-media > video { + width: 100%; + height: 100%; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + object-fit: cover; + text-align: center; + color: var(--mt-color-content-txt); + background-color: var(--mt-color-placeholder); +} +body:has(dialog.mt-dialog[open]) { + overflow: hidden; +} +.mt-dialog { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + border: none; + color: var(--mt-color-content-txt); + background-color: transparent; + padding: 0; + margin: 1rem; + overflow: hidden; +} +.mt-dialog::backdrop { + background-color: var(--mt-color-backdrop); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); +} +.mt-carousel-header { + position: absolute; + top: 0; + right: 0; + z-index: 2; +} +.mt-carousel-body { + width: 100%; + height: 100%; +} +.mt-carousel-scroll { + display: flex; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + list-style: none; + overflow-x: auto; + overflow-y: hidden; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + scrollbar-width: none; +} +.mt-carousel-scroll::-webkit-scrollbar { + display: none; + -webkit-appearance: none; +} +.mt-carousel-item { + scroll-snap-align: center; + width: 100%; + height: 100%; +} +.mt-carousel-media-wrapper { + width: calc(100vw - 2.5rem); + height: 100%; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} +.mt-carousel-media { + width: 100%; + height: 100%; + object-fit: contain; + padding: 2rem; +} +.mt-carousel-next, +.mt-carousel-prev { + position: absolute; + background-color: transparent; + border: none; + padding: 0.5rem; + z-index: 2; +} +.mt-carousel-prev { + left: 0; + padding-left: 0; +} +.mt-carousel-next { + right: 0; + padding-right: 0; +} +.mt-post-preview { + min-height: 4rem; + display: flex; + flex-direction: row; + border: 1px solid var(--mt-color-line-gray); + border-radius: 0.5rem; + color: var(--mt-color-link); + font-size: 0.8rem; + margin: 1rem 0; + overflow: hidden; +} +.mt-post-preview-image { + width: 40%; + align-self: stretch; +} +.mt-post-preview-image img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + color: var(--mt-color-content-txt); +} +.mt-post-preview-noImage { + width: 40%; + font-size: 1.5rem; + align-self: center; + text-align: center; +} +.mt-post-preview-content { + width: 60%; + display: flex; + align-self: center; + flex-direction: column; + padding: 0.5rem 1rem; + gap: 0.5rem; +} +.mt-post-preview-content:has(.mt-post-preview-description.truncate) { + align-self: unset; +} +.mt-post-preview-description { + display: block; + color: var(--mt-color-contrast-gray); +} +.mt-post-preview-description.truncate { + display: -webkit-box; + overflow: hidden; + -webkit-line-clamp: var(--mt-preview-max-lines); + -webkit-box-orient: vertical; +} +.mt-post-preview-description:not(.truncate) .ellipsis::after { + content: "..."; +} +.mt-post-preview-title { + font-weight: 600; +} +.mt-post-counter-bar { + display: flex; + min-width: 6rem; + max-width: 40rem; + justify-content: space-between; + color: var(--mt-color-contrast-gray); +} +.mt-post-counter-bar-favorites, +.mt-post-counter-bar-reblog, +.mt-post-counter-bar-replies { + display: flex; + font-size: 0.75rem; + gap: 0.25rem; + align-items: center; + opacity: 0.6; + cursor: default; +} +.mt-post-counter-bar-favorites > svg, +.mt-post-counter-bar-reblog > svg, +.mt-post-counter-bar-replies > svg { + width: 1rem; + fill: var(--mt-color-contrast-gray); +} +.mt-btn-play { + display: flex; + position: absolute; + width: 3rem; + height: 3rem; + top: calc(50% - 1.5rem); + left: calc(50% - 1.5rem); + justify-content: center; + align-items: center; + background-color: transparent; + border: none; + cursor: pointer; +} +.mt-btn-play > svg { + width: 2.5rem; + height: 2.5rem; + fill: var(--mt-color-bg); + stroke: var(--mt-color-content-txt); + stroke-width: 1px; +} +.mt-post-media.mt-loading-spinner .mt-btn-play { + display: none; +} +.mt-container .mt-btn-dark, +.mt-dialog .mt-btn-dark { + display: flex; + border-radius: 0.25rem; + background-color: var(--mt-color-line-gray); + border: 0; + color: var(--mt-color-content-txt); + font-weight: 600; + font-size: 0.75rem; + text-align: center; + padding: 0.25rem 0.5rem; + line-height: 1.25rem; + vertical-align: top; +} +.mt-dialog .mt-btn-dark { + margin-left: auto; +} +.mt-container .mt-btn-violet, +.mt-container a.mt-btn-violet, +.mt-dialog .mt-btn-violet, +.mt-dialog a.mt-btn-violet { + display: flex; + align-items: center; + gap: 0.5rem; + border-radius: 0.25rem; + border: 0.5rem; + padding: 0.5rem 0.75rem; + font-size: 1rem; + font-weight: 600; + text-align: center; + background-color: var(--mt-color-btn-bg); + color: var(--mt-color-btn-txt); +} +.mt-container .mt-btn-violet:hover, +.mt-container a.mt-btn-violet:hover, +.mt-dialog .mt-btn-violet:hover, +.mt-dialog a.mt-btn-violet:hover { + background-color: var(--mt-color-btn-bg-hover); + text-decoration: none; +} +.mt-post-txt .mt-btn-spoiler-txt { + display: inline-block; + vertical-align: middle; +} +.mt-post-media.mt-loading-spinner > .mt-btn-spoiler-media { + display: none; +} +.mt-post-media > .mt-btn-spoiler-media-show { + position: absolute; + top: 50%; + left: 50%; + z-index: 2; + transform: translate(-50%, -50%); +} +.mt-post-media.mt-post-media-spoiler > .mt-btn-spoiler-media-hide, +.mt-post-media:not([data-media-width-hd]) > .mt-btn-spoiler-media-hide { + display: none; +} +.mt-post-media:not(.mt-post-media-spoiler) > .mt-btn-spoiler-media-show { + display: none; +} +.mt-post-media > .mt-btn-spoiler-media-hide { + position: absolute; + top: 0.5rem; + left: 0.5rem; + z-index: 2; +} +.mt-post-media > .mt-btn-spoiler-media-hide > svg { + fill: var(--mt-color-content-txt); + pointer-events: none; +} +.mt-error { + position: absolute; + left: 50%; + transform: translateX(-50%); + display: flex; + flex-direction: column; + height: calc(100% - 3.5rem); + width: calc(100% - 4.5rem); + justify-content: center; + align-items: center; + color: var(--mt-color-error-txt); + padding: 0.75rem; + text-align: center; +} +.mt-error-icon { + font-size: 2rem; + margin-bottom: 1rem; +} +.mt-error-message { + width: 100%; + padding: 1rem 0; +} +.mt-error-message hr { + color: var(--mt-color-line-gray); +} +.mt-body > .mt-loading-spinner { + position: absolute; + width: 3rem; + height: 3rem; + margin: auto; + top: calc(50% - 1.5rem); + right: calc(50% - 1.5rem); +} +.mt-loading-spinner { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 128 128'%3E%3Cg%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 64 64' to='360 64 64' dur='1000ms' repeatCount='indefinite'/%3E%3Cpath d='M64 6.69a57.3 57.3 0 1 1 0 114.61A57.3 57.3 0 0 1 6.69 64' fill='none' stroke='%23404040' stroke-width='12'/%3E%3C/g%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center center; + background-color: transparent; + background-size: min(2.5rem, calc(100% - 0.5rem)); +} +.mt-footer { + display: flex; + flex-flow: wrap; + margin: auto auto 2rem auto; + padding: 0 1rem; + gap: 1.5rem; + align-items: center; + justify-content: center; +} +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} +@supports (container-type: inline-size) { + @container mt-container (max-width:20rem) { + .mt-body { + padding: 0 0.5rem; + } + .mt-container .mt-post-header-date > a { + white-space: normal; + } + .mt-post-media-wrapper .mt-post-media { + grid-column: 1/3; + } + } +} +@supports not (container-type: inline-size) { + @media screen and (max-width: clamp(20rem,40rem,60rem)) { + .mt-body { + padding: 0 0.5rem; + } + .mt-container .mt-post-header-date > a { + white-space: normal; + } + .mt-post-media-wrapper .mt-post-media { + grid-column: 1/3; + } + } +} diff --git a/static/js/mastodon-timeline.esm.js b/static/js/mastodon-timeline.esm.js new file mode 100644 index 0000000..da7473c --- /dev/null +++ b/static/js/mastodon-timeline.esm.js @@ -0,0 +1,949 @@ +/** + * Mastodon embed timeline + * @author idotj + * @version 4.7.0 + * @url https://gitlab.com/idotj/mastodon-embed-timeline + * @license GNU AGPLv3 + */ +class t { + constructor(t = {}) { + ((this.defaultSettings = { + mtContainerId: "mt-container", + instanceUrl: "https://mastodon.social", + timelineType: "local", + userId: "", + profileName: "", + hashtagName: "", + spinnerClass: "mt-loading-spinner", + defaultTheme: "auto", + maxNbPostFetch: "20", + maxNbPostShow: "20", + dateFormatLocale: "en-GB", + dateFormatOptions: { + day: "2-digit", + month: "short", + year: "numeric", + }, + hideUnlisted: !1, + hideReblog: !1, + hideReplies: !1, + hidePinnedPosts: !1, + hideUserAccount: !1, + txtMaxLines: "", + filterByLanguage: "", + btnShowMore: "SHOW MORE", + btnShowLess: "SHOW LESS", + markdownBlockquote: !1, + hideEmojos: !1, + btnShowContent: "SHOW CONTENT", + hideVideoPreview: !1, + btnPlayVideoTxt: "Load and play video", + hidePreviewLink: !1, + previewMaxLines: "", + hideCounterBar: !1, + disableCarousel: !1, + carouselCloseTxt: "Close carousel", + carouselPrevTxt: "Previous media item", + carouselNextTxt: "Next media item", + btnSeeMore: "See more posts at Mastodon", + btnReload: "Refresh", + insistSearchContainer: !1, + insistSearchContainerTime: "3000", + }), + (this.mtSettings = { ...this.defaultSettings, ...t }), + this.#t(), + (this.linkHeader = {}), + (this.mtContainerNode = ""), + (this.mtBodyNode = ""), + (this.fetchedData = {}), + this.#e(() => { + this.#i(); + })); + } + #t() { + Number(this.mtSettings.maxNbPostShow) > + Number(this.mtSettings.maxNbPostFetch) && + (console.error( + `Please check your settings! The maximum number of posts to show is bigger than the maximum number of posts to fetch. Changing the value of "maxNbPostFetch" to: ${this.mtSettings.maxNbPostShow}`, + ), + (this.mtSettings.maxNbPostFetch = this.mtSettings.maxNbPostShow)); + } + #e(t) { + "undefined" != typeof document && "complete" === document.readyState + ? t() + : "undefined" != typeof document && + "complete" !== document.readyState && + document.addEventListener("DOMContentLoaded", t()); + } + #i() { + const t = () => { + ((this.mtContainerNode = document.getElementById( + this.mtSettings.mtContainerId, + )), + (this.mtBodyNode = + this.mtContainerNode.getElementsByClassName("mt-body")[0]), + this.#s(), + this.#a("newTimeline")); + }; + if (this.mtSettings.insistSearchContainer) { + const e = performance.now(), + i = () => { + if (document.getElementById(this.mtSettings.mtContainerId)) + t(); + else { + performance.now() - e < + this.mtSettings.insistSearchContainerTime + ? requestAnimationFrame(i) + : console.error( + `Impossible to find the
container with id: "${this.mtSettings.mtContainerId}" after several attempts for ${this.mtSettings.insistSearchContainerTime / 1e3} seconds`, + ); + } + }; + i(); + } else + document.getElementById(this.mtSettings.mtContainerId) + ? t() + : console.error( + `Impossible to find the
container with id: "${this.mtSettings.mtContainerId}". Please try to add the option 'insistSearchContainer: true' when initializing the script`, + ); + } + mtUpdate() { + this.#e(() => { + (this.mtBodyNode.replaceChildren(), + this.mtBodyNode.insertAdjacentHTML( + "afterbegin", + '
', + ), + this.#a("updateTimeline")); + }); + } + mtColorTheme(t) { + this.#e(() => { + this.mtContainerNode.setAttribute("data-theme", t); + }); + } + #s() { + if ("auto" === this.mtSettings.defaultTheme) { + let t = window.matchMedia("(prefers-color-scheme: dark)"); + (t.matches ? this.mtColorTheme("dark") : this.mtColorTheme("light"), + t.addEventListener("change", (t) => { + t.matches + ? this.mtColorTheme("dark") + : this.mtColorTheme("light"); + })); + } else this.mtColorTheme(this.mtSettings.defaultTheme); + } + #o() { + return new Promise((t, e) => { + const i = this.mtSettings.instanceUrl + ? `${this.mtSettings.instanceUrl}/api/v1/` + : this.#n( + "Please check your instanceUrl value", + "⚠️", + ), + s = this.#r(i), + a = Object.entries(s).map(([t, i]) => + this.#l(i, t) + .then((e) => ({ [t]: e })) + .catch( + (i) => ( + e( + new Error( + "Something went wrong getting the timeline data.", + ), + ), + this.#n(i.message), + { [t]: [] } + ), + ), + ); + Promise.all(a).then(async (e) => { + if ( + ((this.fetchedData = e.reduce( + (t, e) => ({ ...t, ...e }), + {}, + )), + !this.mtSettings.hidePinnedPosts && + void 0 !== this.fetchedData.pinned?.length && + 0 !== this.fetchedData.pinned.length) + ) { + const t = this.fetchedData.pinned.map((t) => ({ + ...t, + pinned: !0, + })); + this.fetchedData.timeline = [ + ...t, + ...this.fetchedData.timeline, + ]; + } + if (this.#d()) t(); + else { + do { + await this.#m(); + } while (!this.#d() && this.linkHeader.next); + t(); + } + }); + }); + } + #r(t) { + const { + timelineType: e, + userId: i, + hashtagName: s, + hideReblog: a, + hideReplies: o, + maxNbPostFetch: n, + hidePinnedPosts: r, + hideEmojos: l, + } = this.mtSettings, + d = {}; + switch (e) { + case "profile": + if (!i) { + this.#n( + "Please check your userId value", + "⚠️", + ); + break; + } + ((d.timeline = `${t}accounts/${i}/statuses?limit=${n}`), + r || (d.pinned = `${t}accounts/${i}/statuses?pinned=true`)); + break; + case "hashtag": + if (!s) { + this.#n( + "Please check your hashtagName value", + "⚠️", + ); + break; + } + d.timeline = `${t}timelines/tag/${s}?limit=${n}`; + break; + case "local": + d.timeline = `${t}timelines/public?local=true&limit=${n}`; + break; + default: + this.#n( + "Please check your timelineType value", + "⚠️", + ); + } + return ( + a && (d.timeline += "&exclude_reblogs=true"), + o && (d.timeline += "&exclude_replies=true"), + l || (d.emojos = `${t}custom_emojis`), + d + ); + } + async #l(t, e) { + const i = await fetch(t); + if (!i.ok) + throw new Error( + `\n Failed to fetch the following Url:
${t}
Error status: ${i.status}
Error message: ${i.statusText}\n `, + ); + const s = await i.json(); + return ( + "timeline" === e && + i.headers.get("Link") && + (this.linkHeader = this.#h(i.headers.get("Link"))), + s + ); + } + #d() { + return ( + this.fetchedData.timeline.length >= + Number(this.mtSettings.maxNbPostFetch) + ); + } + #m() { + return new Promise((t) => { + this.linkHeader.next + ? this.#l(this.linkHeader.next, "timeline") + .then((e) => { + ((this.fetchedData.timeline = [ + ...this.fetchedData.timeline, + ...e, + ]), + t()); + }) + .catch( + (t) => ( + reject( + new Error( + "Something went wrong fetching more posts.", + ), + ), + this.#n(t.message), + { [key]: [] } + ), + ) + : t(); + }); + } + #h(t) { + const e = t + .split(", ") + .map((t) => t.split("; ")) + .map((t) => [ + t[1].replace(/"/g, "").replace("rel=", ""), + t[0].slice(1, -1), + ]); + return Object.fromEntries(e); + } + async #a(t) { + await this.#o(); + const { + hideUnlisted: e, + maxNbPostShow: i, + filterByLanguage: s, + } = this.mtSettings, + a = this.fetchedData.timeline; + this.mtBodyNode.replaceChildren(); + if ( + (a + .filter((t) => { + const i = + "public" === t.visibility || + (!e && "unlisted" === t.visibility), + a = t.language || (t.reblog ? t.reblog.language : null); + return i && ("" === s || a === s); + }) + .forEach((t, e) => { + e < i && this.#c(t, e); + }), + "" !== this.mtBodyNode.innerHTML) + ) + "newTimeline" === t + ? (this.#p(), + this.#g(), + this.#u(0), + this.#v(), + (this.mtSettings.btnSeeMore || this.mtSettings.btnReload) && + this.#b()) + : "updateTimeline" === t + ? this.#p() + : this.#n( + "The function buildTimeline() was expecting a param", + ); + else { + const t = `No posts to show
${a?.length || 0} posts have been fetched from the server
This may be due to an incorrect configuration with the parameters or with the filters applied (to hide certains type of posts)`; + this.#n(t, "📭"); + } + } + #g() { + ("0" !== this.mtSettings.txtMaxLines && + 0 !== this.mtSettings.txtMaxLines.length && + this.mtBodyNode.parentNode.style.setProperty( + "--mt-txt-max-lines", + this.mtSettings.txtMaxLines, + ), + "0" !== this.mtSettings.previewMaxLines && + 0 !== this.mtSettings.previewMaxLines.length && + this.mtBodyNode.parentNode.style.setProperty( + "--mt-preview-max-lines", + this.mtSettings.previewMaxLines, + )); + } + #u(t) { + const e = this.mtBodyNode.getElementsByTagName("article"); + for (let i = 0; i < t; i++) e[i].setAttribute("aria-setsize", t); + } + #c(t, e) { + this.mtBodyNode.insertAdjacentHTML("beforeend", this.#w(t, e)); + } + #w(t, e) { + const i = Boolean(t.reblog), + s = i ? t.reblog : t, + { + url: a, + created_at: o, + replies_count: n, + reblogs_count: r, + favourites_count: l, + } = s, + { + avatar: d, + url: m, + username: h, + display_name: c, + emojis: p, + } = s.account, + g = + '
' +
+                this.#f(h) +
+                ' avatar
' + + (i + ? '
' +
+                      this.#f(t.account.username) +
+                      ' avatar
' + : "") + + "
", + u = + '
' + + (!this.mtSettings.hideEmojos && c ? this.#x(c, p) : c || h) + + "" + + (this.mtSettings.hideUserAccount + ? "" + : '
") + + "
", + v = this.#S(o), + b = + '
' + + (t.pinned + ? '' + : "") + + '" + + (t.edited_at ? " *" : "") + + "
", + w = + this.mtSettings.hidePreviewLink || (!t.card && !t.reblog?.card) + ? "" + : this.#y(i ? t.reblog.card : t.card), + f = + "0" !== this.mtSettings.txtMaxLines && + this.mtSettings.txtMaxLines.length + ? " truncate" + : ""; + let x = ""; + const S = s.spoiler_text ? s.spoiler_text : s.content, + y = + '
' + + this.#L(s.content) + + w + + "
"; + S && + (x = + '
' + + this.#L(S) + + (s.spoiler_text ? y : "") + + "
"); + const L = [ + ...t.media_attachments, + ...(t.reblog?.media_attachments || []), + ] + .map((t) => this.#T(t, s.sensitive)) + .join(""), + T = L ? `
${L}
` : "", + N = t.poll + ? '
    ' + + t.poll.options + .map(function (t) { + return "
  • " + t.title + "
  • "; + }) + .join("") + + "
" + : "", + M = this.mtSettings.hideCounterBar + ? "" + : '
' + + this.#N("replies", n) + + this.#N("reblog", r) + + this.#N("favorites", l) + + "
"; + return ( + '
' + + g + + u + + b + + "
" + + x + + T + + N + + (s.spoiler_text ? "" : w) + + M + + "
" + ); + } + #N(t, e) { + return `
${{ replies: '', reblog: '', favorites: '' }[t]}${e}
`; + } + #M(t, e) { + function i(t, e) { + let i = e.replace(/\s+/g, "").toLowerCase(); + return ( + !( + !["src", "href", "xlink:href"].includes(t) || + (!i.includes("javascript:") && !i.includes("data:")) + ) || + !!t.startsWith("on") || + void 0 + ); + } + function s(t) { + let e = t.attributes; + for (let { name: s, value: a } of e) + i(s, a) && t.removeAttribute(s); + } + let a = + new DOMParser().parseFromString(t, "text/html").body || + document.createElement("body"); + return ( + (function (t) { + let e = t.querySelectorAll("script"); + for (let t of e) t.remove(); + })(a), + (function t(e) { + let i = e.children; + for (let e of i) (s(e), t(e)); + })(a), + e ? a.childNodes : a.innerHTML + ); + } + #L(t) { + let e = t; + return ( + (e = this.#M(e, !1)), + (e = this.#k(e)), + this.mtSettings.hideEmojos || + (e = this.#x(e, this.fetchedData.emojos)), + this.mtSettings.markdownBlockquote && + (e = this.#C( + e, + "

>", + "

", + "

", + "

", + )), + e + ); + } + #k(t) { + let e = t.replaceAll('rel="tag"', 'rel="tag" target="_blank"'); + return ( + (e = e.replaceAll( + 'class="u-url mention"', + 'class="u-url mention" target="_blank"', + )), + e + ); + } + #C(t, e, i, s, a) { + if (t.includes(e)) { + const o = new RegExp(e + "(.*?)" + i, "gi"); + return t.replace(o, s + "$1" + a); + } + return t; + } + #f(t) { + return (t ?? "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); + } + #x(t, e) { + if (t.includes(":")) { + for (const i of e) { + const e = new RegExp(`\\:${i.shortcode}\\:`, "g"); + t = t.replace( + e, + `Emoji ${i.shortcode}`, + ); + } + return t; + } + return t; + } + #S(t) { + const e = new Date(t); + return new Intl.DateTimeFormat( + this.mtSettings.dateFormatLocale, + this.mtSettings.dateFormatOptions, + ).format(e); + } + #T(t, e = !1) { + const { type: i, url: s, preview_url: a, description: o, meta: n } = t, + { original: r, small: l } = n, + { + spinnerClass: d, + btnShowContent: m, + btnPlayVideoTxt: h, + hideVideoPreview: c, + } = this.mtSettings, + p = + '", + g = + ' class="mt-post-media ' + + (e ? "mt-post-media-spoiler " : "") + + (d || "") + + '" data-media-type="' + + i + + '" data-media-url-hd="' + + s + + '"' + + (o ? ' data-media-alt-txt="' + this.#f(o) + '"' : "") + + ' data-media-width-hd="' + + r.width + + '" data-media-height-hd="' + + r.height + + '" style="padding-top: calc(100%/' + + l?.aspect + + ')">'; + return "image" === i + ? "
' + : "audio" === i + ? '
' + + (e ? p : "") + + '' + + (a + ? '' +
+                      (o ? this.#f(o) : ' + : "") + + "
" + : "video" === i || "gifv" === i + ? c + ? "
' + : "' + : ""; + } + #P(t, e) { + let i = document.createElement("dialog"); + ((i.id = t), + i.classList.add("mt-dialog"), + (i.dataset.theme = this.mtContainerNode.getAttribute("data-theme")), + (i.innerHTML = e), + document.body.prepend(i), + i.showModal(), + i.addEventListener("close", () => { + document.body.removeChild(i); + })); + } + #E(t) { + const e = Array.from(t.target.parentNode.parentNode.children).filter( + (t) => !t.classList.contains("mt-post-media-spoiler"), + ), + i = e.indexOf(t.target.parentNode) + 1; + let s = []; + e.forEach((t, e) => { + let i = ""; + i = + "gifv" === t.getAttribute("data-media-type") || + "video" === t.getAttribute("data-media-type") + ? `\n \n ` + : `\n ${t.getAttribute(\n `; + const a = `\n \n `; + s.push(a); + }); + const a = `\n \n\n \n\n \n\n \n `; + (this.#P("mt-carousel", a), s.length >= 2 && this.#$(e.length, i)); + } + #$(t, e) { + let i = e; + const s = document.getElementById("mt-carousel-scroll"); + let a = 0, + o = !1; + const n = document.getElementById("mt-carousel-prev"), + r = document.getElementById("mt-carousel-next"), + l = (t, e = "smooth") => { + document + .getElementById("mt-carousel-" + t) + .scrollIntoView({ behavior: e }); + }; + l(i, "instant"); + const d = () => { + (clearTimeout(a), + (a = setTimeout(() => { + (o && + ((i = (() => { + const t = + (s.scrollLeft + s.clientWidth) / s.clientWidth; + return Math.round(t + Number.EPSILON); + })()), + m()), + (o = !0)); + }, 60))); + }; + s.addEventListener("scroll", d); + const m = () => { + ((n.hidden = 1 === i), (r.hidden = i === t)); + }, + h = (e) => { + const s = e.target.closest("button")?.id; + ("mt-carousel-next" === s + ? ((o = !1), ++i, i > t && (i = t), l(i), m()) + : "mt-carousel-prev" === s && + ((o = !1), --i, i < 1 && (i = 1), l(i), m()), + "mt-carousel-close" === s && p()); + }; + document.addEventListener("click", h); + const c = (t) => { + ("Escape" !== t.key && 27 !== t.keyCode) || p(); + }; + document.addEventListener("keydown", c); + const p = () => { + (s.removeEventListener("scroll", d), + document.removeEventListener("click", h), + document.removeEventListener("keydown", c)); + }; + } + #B(t) { + const e = t.target.closest("[data-media-type]"), + i = e.dataset.mediaUrlHd; + (e.replaceChildren(), + (e.innerHTML = ``)); + } + #A(t) { + const e = t.target, + i = e.nextSibling, + s = "true" === e.getAttribute("aria-expanded"); + (i.classList.toggle("spoiler-txt-hidden", s), + i.classList.toggle("spoiler-txt-visible", !s), + e.setAttribute("aria-expanded", !s), + (e.textContent = s + ? this.mtSettings.btnShowMore + : this.mtSettings.btnShowLess)); + } + #H(t) { + const e = t.target; + e.parentNode.classList.toggle( + "mt-post-media-spoiler", + !e.classList.contains("mt-btn-spoiler-media-show"), + ); + } + #y(t) { + const { + url: e, + image: i, + image_description: s, + provider_name: a, + title: o, + description: n, + author_name: r, + } = t, + { previewMaxLines: l, spinnerClass: d } = this.mtSettings; + let m = ""; + return ( + "0" !== l && + n && + (m = + '' + + this.#q(n) + + ""), + '' + + (i + ? '
' +
+                      this.#f(s) +
+                      '
' + : '
📄
') + + '
' + + (a + ? '' + + this.#q(a) + + "" + : "") + + '' + + o + + "" + + m + + (r + ? '' + + this.#q(r) + + "" + : "") + + "
" + ); + } + #q(t) { + return new DOMParser().parseFromString(t, "text/html").body.textContent; + } + #b() { + const { + btnSeeMore: t, + btnReload: e, + timelineType: i, + profileName: s, + hashtagName: a, + instanceUrl: o, + } = this.mtSettings; + let n = "", + r = ""; + if (t) { + let e = ""; + switch (i) { + case "profile": + s + ? (e = s) + : this.#n( + "Please check your profileName value", + "⚠️", + ); + break; + case "hashtag": + e = "tags/" + a; + break; + case "local": + e = "public/local"; + } + n = + '' + + t + + ""; + } + if ( + (e && + (r = + '"), + this.mtBodyNode.parentNode.insertAdjacentHTML( + "beforeend", + '", + ), + e) + ) { + const t = this.mtContainerNode.querySelector(".btn-refresh"); + t && t.addEventListener("click", () => this.mtUpdate()); + } + } + #v() { + (this.mtBodyNode.addEventListener("click", (t) => { + const e = t.target, + i = e.localName, + s = e.parentNode; + (("article" == i || + "article" == e.offsetParent?.localName || + (this.mtSettings.disableCarousel && + "image" === s.getAttribute("data-media-type"))) && + this.#D(t), + e.classList.contains("mt-btn-spoiler-txt") && this.#A(t), + e.classList.contains("mt-btn-spoiler-media") && this.#H(t), + this.mtSettings.disableCarousel || + "img" != i || + ("image" !== s.getAttribute("data-media-type") && + "audio" !== s.getAttribute("data-media-type")) || + this.#E(t), + ("mt-btn-play" == e.className || + ("svg" == i && "mt-btn-play" == s.className) || + ("path" == i && "mt-btn-play" == s.parentNode.className) || + ("img" == i && + ("video" === s.getAttribute("data-media-type") || + "gifv" === s.getAttribute("data-media-type")))) && + this.#B(t)); + }), + this.mtBodyNode.addEventListener("keydown", (t) => { + const e = t.target.localName; + "Enter" === t.key && "article" == e && this.#D(t); + })); + } + #D(t) { + const e = t.target.closest(".mt-post")?.dataset.location; + if (!e) return; + const i = t.target.localName; + if ( + "a" === i || + "span" === i || + "button" === i || + "bdi" === i || + "time" === i + ) + return; + const s = t.target.className; + if ("mt-post-media-spoiler" === s || "mt-post-preview-noImage" === s) + return; + const a = t.target.parentNode?.className; + "mt-post-avatar-image-big" !== a && + "mt-post-avatar-image-small" !== a && + "mt-post-header-user-name" !== a && + "mt-post-preview-image" !== a && + "mt-post-preview" !== a && + window.open(e, "_blank", "noopener"); + } + #p() { + const t = (e) => { + (e.target.parentNode.classList.remove(this.mtSettings.spinnerClass), + e.target.removeEventListener("load", t), + e.target.removeEventListener("error", t)); + }; + this.mtBodyNode + .querySelectorAll(`.${this.mtSettings.spinnerClass} > img`) + .forEach((e) => { + (e.addEventListener("load", t), e.addEventListener("error", t)); + }); + } + #n(t, e) { + const i = e || "❌"; + throw ( + (this.mtBodyNode.innerHTML = `\n
\n ${i}\n Oops, something's happened:\n
${t}
\n
`), + this.mtBodyNode.setAttribute("role", "none"), + new Error( + "Stopping the script due to an error building the timeline.", + ) + ); + } +} +export { t as Init }; -- cgit v1.2.3