Merge branch 'develop' of https://codeberg.org/calckey/calckey into upstream

This commit is contained in:
freeplay 2023-07-02 13:01:54 -04:00
commit 567d94196a
33 changed files with 455 additions and 195 deletions

View file

@ -1601,6 +1601,8 @@ _aboutMisskey:
morePatrons: També agraïm el suport de molts altres ajudants que no figuren aquí.
Gràcies! 🥰
patrons: Mecenes de Calckey
patronsList: Llistats cronològicament, no per la quantitat donada. Fes una donació
amb l'enllaç de dalt per veure el teu nom aquí!
unknown: Desconegut
pageLikesCount: Nombre de pàgines amb M'agrada
youAreRunningUpToDateClient: Estás fent servir la versió del client més nova.
@ -2082,11 +2084,7 @@ _experiments:
alpha: Alfa
beta: Beta
release: Publicà
enablePostEditing: Activà l'edició de publicacions
title: Experiments
postEditingCaption: Mostra l'opció perquè els usuaris editin les seves publicacions
mitjançant el menú d'opcions de publicació, i permet rebre publicacions editades
d'altres servidors.
enablePostImports: Activar l'importació de publicacions
postImportsCaption: Permet els usuaris importar publicacions desde comptes a Calckey,
Misskey, Mastodon, Akkoma i Pleroma. Pot fer que el servidor vagi més lent durant

View file

@ -2095,10 +2095,7 @@ jumpToPrevious: Zum Vorherigen springen
silencedWarning: Diese Meldung wird angezeigt, weil diese Nutzer von Servern stammen,
die Ihr Administrator abgeschaltet hat, so dass es sich möglicherweise um Spam handelt.
_experiments:
enablePostEditing: Beitragsbearbeitung ermöglichen
title: Funktionstests
postEditingCaption: Zeigt die Option für Nutzer an, ihre bestehenden Beiträge über
das Menü "Beitragsoptionen" zu bearbeiten
enablePostImports: Beitragsimporte aktivieren
postImportsCaption: Erlaubt es Nutzer:innen ihre Posts von alten Calckey, Misskey,
Mastodon, Akkoma und Pleroma Accounts zu importieren. Bei Engpässen in der Warteschlange
@ -2152,3 +2149,4 @@ clipsDesc: Clips sind wie teilbare, kategorisierte Lesezeichen. Du kannst Clips
Menü individueller Posts aus erstellen.
channelFederationWarn: Kanäle föderieren noch nicht zu anderen Servern
reactionPickerSkinTone: Bevorzugte Emoji-Hautfarbe
swipeOnMobile: Wischen zwischen den Seiten erlauben

View file

@ -1213,6 +1213,7 @@ _aboutMisskey:
morePatrons: "We also appreciate the support of many other helpers not listed here.
Thank you! 🥰"
patrons: "Calckey patrons"
patronsList: "Listed chronologically, not by donation size. Donate with the link above to get your name on here!"
_nsfw:
respect: "Hide NSFW media"
ignore: "Don't hide NSFW media"
@ -2069,9 +2070,6 @@ _deck:
direct: "Direct messages"
_experiments:
title: "Experiments"
enablePostEditing: "Enable post editing"
postEditingCaption: "Shows the option for users to edit their existing posts via\
\ the post options menu, and allows post edits from other instances to be recieved."
enablePostImports: "Enable post imports"
postImportsCaption: "Allows users to import their posts from past Calckey,\
\ Misskey, Mastodon, Akkoma, and Pleroma accounts. It may cause slowdowns during\

View file

@ -2028,7 +2028,7 @@ flagShowTimelineRepliesDescription: Si activé, affiche dans le fil les réponse
_experiments:
alpha: Alpha
beta: Beta
enablePostEditing: Autoriser l'édition de note
enablePostImports: Autoriser l'importation de messages
title: Expérimentations
findOtherInstance: Trouver un autre serveur
userSaysSomethingReasonQuote: '{name} a cité une note contenant {reason}'

View file

@ -1887,9 +1887,7 @@ hiddenTagsDescription: 'トレンドと「みつける」から除外したい
hiddenTags: 非表示にするハッシュタグ
apps: "アプリ"
_experiments:
enablePostEditing: 投稿の編集機能を有効にする
title: 試験的な機能
postEditingCaption: 投稿のメニューに既存の投稿を編集するボタンを表示し、他サーバーの編集も受信できるようにします。
postImportsCaption:
ユーザーが過去の投稿をCalckey・Misskey・Mastodon・Akkoma・Pleromaからインポートすることを許可します。キューが溜まっているときにインポートするとサーバーに負荷がかかる可能性があります。
enablePostImports: 投稿のインポートを有効にする

View file

@ -1,7 +1,7 @@
---
_lang_: "简体中文"
headlineMisskey: "通过帖子连接在一起的网络"
introMisskey: "欢迎Misskey是一个开源的、去中心化的“微博客”服务。\n通过编写「帖文」来和大家分享你的以及你周围的事情吧📡\n通过「回应」功能可以让你快速地对大家的帖文表达反馈👍\n来探索新的世界吧🚀"
introMisskey: "欢迎Misskey是一个开源的、去中心化的“微博客”服务。\n通过编写「帖文」来和大家分享你的以及你周围的事情吧📡\n通过「回应」功能可以让你快速地对大家的帖文表达反馈👍\n\
来探索新的世界吧!🚀"
monthAndDay: "{month}月 {day}日"
search: "搜索"
notifications: "通知"
@ -14,9 +14,9 @@ gotIt: "我明白了"
cancel: "取消"
enterUsername: "输入用户名"
renotedBy: "由 {user} 转贴"
noNotes: "没有帖"
noNotes: "没有帖"
noNotifications: "无通知"
instance: "实例"
instance: "服务器"
settings: "设置"
basicSettings: "基本设置"
otherSettings: "其他设置"
@ -64,7 +64,7 @@ import: "导入"
export: "导出"
files: "文件"
download: "下载"
driveFileDeleteConfirm: "要删除「{name}」文件吗?附加此文件的帖子也会被删除。"
driveFileDeleteConfirm: "要删除文件「{name}」吗?它将被所有作为附件包含它的帖子中删除。"
unfollowConfirm: "要取消对{name}的关注吗?"
exportRequested: "导出请求已提交,这可能需要花一些时间,导出的文件将保存到网盘中。"
importRequested: "导入请求已提交,这可能需要花一点时间。"
@ -166,7 +166,7 @@ selectUser: "选择用户"
recipient: "收件人"
annotation: "注解"
federation: "联合"
instances: "实例"
instances: "服务器"
registeredAt: "初次观测"
latestRequestSentAt: "上次发送的请求"
latestRequestReceivedAt: "上次收到的请求"
@ -186,14 +186,14 @@ jobQueue: "作业队列"
cpuAndMemory: "CPU和内存"
network: "网络"
disk: "存储"
instanceInfo: "实例信息"
instanceInfo: "服务器信息"
statistics: "统计"
clearQueue: "清除队列"
clearQueueConfirmTitle: "确定清除队列?"
clearQueueConfirmText: "未送达的帖子将不会送达。 通常,您不需要这样做。"
clearCachedFiles: "清除缓存"
clearCachedFilesConfirm: "确定要清除缓存文件?"
blockedInstances: "被阻拦的实例"
blockedInstances: "已屏蔽的服务器"
blockedInstancesDescription: "设定要阻拦的实例,以换行来进行分割。被阻拦的实例将无法与本实例进行交换通讯。"
muteAndBlock: "屏蔽/拉黑"
mutedUsers: "已屏蔽用户"
@ -309,8 +309,8 @@ unwatch: "取消关注"
accept: "允许"
reject: "拒绝"
normal: "正常"
instanceName: "实例名称"
instanceDescription: "实例介绍"
instanceName: "服务器名称"
instanceDescription: "服务器简介"
maintainerName: "管理员名称"
maintainerEmail: "管理员电子邮箱"
tosUrl: "服务条款URL"
@ -321,7 +321,7 @@ dayX: "{day}日"
monthX: "{month}月"
yearX: "{year}年"
pages: "页面"
integration: "关联"
integration: "整合"
connectService: "连接"
disconnectService: "断开连接"
enableLocalTimeline: "启用本地时间线功能"
@ -600,7 +600,7 @@ testEmail: "邮件发送测试"
wordMute: "文字屏蔽"
regexpError: "正则表达式错误"
regexpErrorDescription: "{tab} 屏蔽文字的第 {line} 行的正则表达式有错误:"
instanceMute: "实例的屏蔽"
instanceMute: "服务器静音"
userSaysSomething: "{name}说了什么"
makeActive: "启用"
display: "显示"
@ -643,7 +643,7 @@ instanceTicker: "帖子的实例信息"
waitingFor: "等待{x}"
random: "随机"
system: "系统"
switchUi: "切换界面"
switchUi: "界面"
desktop: "桌面"
clip: "便签"
createNew: "新建"
@ -755,7 +755,7 @@ active: "活动"
offline: "离线"
notRecommended: "不推荐"
botProtection: "Bot防御"
instanceBlocking: "被阻拦的实例"
instanceBlocking: "联邦管理"
selectAccount: "选择账户"
switchAccount: "切换账户"
enabled: "已启用"
@ -816,7 +816,7 @@ controlPanel: "控制面板"
manageAccounts: "管理账户"
makeReactionsPublic: "将回应设置为公开"
makeReactionsPublicDescription: "将您发表过的回应设置成公开可见。"
classic: "经典"
classic: "居中"
muteThread: "屏蔽帖子列表"
unmuteThread: "取消屏蔽帖子列表"
ffVisibility: "连接的可见范围"
@ -896,7 +896,10 @@ shuffle: "随机"
account: "账户"
move: "移动"
customKaTeXMacro: "自定义 KaTeX 宏"
customKaTeXMacroDescription: "使用宏来轻松的输入数学表达式吧!宏的用法与 LaTeX 中的命令定义相同。你可以使用 \\newcommand{\\name}{content} 或 \\newcommand{\\name}[number of arguments]{content} 来输入数学表达式。举个例子,\\newcommand{\\add}[2]{#1 + #2} 会将 \\add{3}{foo} 展开为 3 + foo。此外宏名称外的花括号 {} 可以被替换为圆括号 () 和方括号 [],这会影响用于参数的括号。每行只能够定义一个宏,无法在中间换行,且无效的行将被忽略。只支持简单字符串替换功能,不支持高级语法,如条件分支等。"
customKaTeXMacroDescription: "使用宏来轻松的输入数学表达式吧!宏的用法与 LaTeX 中的命令定义相同。你可以使用 \\newcommand{\\
name}{content} 或 \\newcommand{\\name}[number of arguments]{content} 来输入数学表达式。举个例子,\\
newcommand{\\add}[2]{#1 + #2} 会将 \\add{3}{foo} 展开为 3 + foo。此外宏名称外的花括号 {} 可以被替换为圆括号
() 和方括号 [],这会影响用于参数的括号。每行只能够定义一个宏,无法在中间换行,且无效的行将被忽略。只支持简单字符串替换功能,不支持高级语法,如条件分支等。"
enableCustomKaTeXMacro: "启用自定义 KaTeX 宏"
_sensitiveMediaDetection:
description: "可以使用机器学习技术自动检测敏感媒体,以便进行审核。服务器负载将略微增加。"
@ -981,6 +984,7 @@ _aboutMisskey:
donate: "赞助Misskey"
morePatrons: "还有很多其他的人也在支持我们,非常感谢🥰"
patrons: "支持者"
patronsList: 按时间顺序而不是捐赠金额排列。通过上面的链接捐款,让您的名字出现在这里!
_nsfw:
respect: "隐藏敏感内容"
ignore: "不隐藏敏感内容"
@ -1051,6 +1055,24 @@ _mfm:
rotateDescription: "旋转指定的角度。"
plain: "简洁"
plainDescription: "禁用所有内部语法。"
crop: 裁剪
scale: 缩放
position: 位置
fade: 渐淡
advanced: 高级 MFM
background: 背景色
fadeDescription: 内容淡入和淡出。
warn: MFM 可能包含快速移动或华丽的动画
advancedDescription: 如果禁用,则仅允许基本标记,除非正在播放动态 MFM
foreground: 前景色
backgroundDescription: 更改文本的背景色。
play: 播放 MFM
alwaysPlay: 始终自动播放所有动态的 MFM
stop: 停止播放 MFM
positionDescription: 将内容移动指定的量。
cropDescription: 裁剪内容。
scaleDescription: 按指定量缩放内容。
foregroundDescription: 更改文本的前景色。
_instanceTicker:
none: "不显示"
remote: "仅远程用户"
@ -1059,6 +1081,7 @@ _serverDisconnectedBehavior:
reload: "自动重载"
dialog: "对话框警告"
quiet: "安静警告"
nothing: 什么也不做
_channel:
create: "创建频道"
edit: "编辑频道"
@ -1068,7 +1091,7 @@ _channel:
owned: "管理中"
following: "正在关注"
usersCount: "有{n}人参与"
notesCount: "有{n}个帖子"
notesCount: "{n} 帖子"
nameAndDescription: "名称与描述"
nameOnly: "仅名称"
_menuDisplay:
@ -1084,7 +1107,7 @@ _wordMute:
hardDescription: "防止将具有指定条件的帖子添加到时间线。 即使您更改条件,未添加的帖文也会被排除在外。"
soft: "软屏蔽"
hard: "硬屏蔽"
mutedNotes: "被屏蔽的帖子"
mutedNotes: "已静音的帖子"
_instanceMute:
instanceMuteDescription: "屏蔽配置实例中的所有帖子和转帖,包括实例的用户回复。"
instanceMuteDescription2: "设置时用换行符来分隔"
@ -1165,7 +1188,7 @@ _theme:
accentLighten: "强调色(浅)"
fgHighlighted: "高亮显示文本"
_sfx:
note: "帖子"
note: "新的帖子"
noteMy: "我的帖子"
notification: "通知"
chat: "聊天"
@ -1178,7 +1201,7 @@ _ago:
secondsAgo: "{n}秒前"
minutesAgo: "{n}分前"
hoursAgo: "{n}小时前"
daysAgo: "{n}前"
daysAgo: "{n}前"
weeksAgo: "{n}周前"
monthsAgo: "{n}月前"
yearsAgo: "{n}年前"
@ -1218,6 +1241,21 @@ _2fa:
step3: "输入您的应用提供的动态口令以完成设置。"
step4: "从现在开始,任何登录操作都将要求您提供动态口令。"
securityKeyInfo: "您可以设置使用支持FIDO2的硬件安全密钥、设备上的指纹或PIN来保护您的登录过程。"
renewTOTPOk: 重新配置
renewTOTPCancel: 取消
token: 2FA 令牌
renewTOTP: 重新配置身份验证器应用程序
registerTOTPBeforeKey: 请设置一个认证器应用来注册一个安全或通行密钥。
renewTOTPConfirm: 这将导致您之前的应用程序中的验证码停止工作
step3Title: 输入验证码
step2Click: 点击此二维码将允许您在安全密钥或手机验证器应用中注册 2FA。
securityKeyNotSupported: 您的浏览器不支持安全密钥。
securityKeyName: 输入密钥名称
chromePasskeyNotSupported: 目前不支持 Chrome passkeys。
tapSecurityKey: 请按照您的浏览器的指示注册安全或通行密钥
removeKey: 移除安全密钥
removeKeyConfirm: 真的要删除 {name} 密钥吗?
whyTOTPOnlyRenew: 只要注册了安全密钥,就无法删除身份验证器应用程序。
_permissions:
"read:account": "查看账户信息"
"write:account": "更改帐户信息"
@ -1258,12 +1296,15 @@ _auth:
pleaseGoBack: "请返回到应用程序"
callback: "回到应用程序"
denied: "拒绝访问"
allPermissions: 完全的账户访问权限
copyAsk: 请将以下授权码粘贴到应用程序中:
_antennaSources:
all: "所有帖子"
homeTimeline: "已关注用户的帖子"
users: "来自指定用户的帖子"
userList: "来自指定列表中的帖子"
userGroup: "来自指定群组中用户的帖子"
instances: 服务器上所有用户的帖子
_weekday:
sunday: "星期日"
monday: "星期一"
@ -1280,21 +1321,26 @@ _widgets:
trends: "趋势"
clock: "时钟"
rss: "RSS阅读器"
rssTicker: "RSS Ticker"
rssTicker: "RSS滚动条"
activity: "活动"
photos: "照片"
digitalClock: "数字时钟"
unixClock: "UNIX时钟"
federation: "联邦宇宙"
instanceCloud: "实例云"
postForm: "投稿窗口"
instanceCloud: "服务器云端"
postForm: "发布窗口"
slideshow: "幻灯片展示"
button: "按钮"
onlineUsers: "在线用户"
jobQueue: "作业队列"
serverMetric: "服务器监控"
serverMetric: "服务器指标"
aiscript: "AiScript控制台"
aichan: "小蓝"
userList: 用户列表
meiliStatus: 服务器状态
meiliIndexCount: 已索引的帖子
meiliSize: 索引大小
serverInfo: 服务器信息
_cw:
hide: "隐藏"
show: "查看更多"
@ -1325,7 +1371,7 @@ _poll:
_visibility:
public: "公开"
publicDescription: "您的帖子将出现在全局时间线上"
home: "首页"
home: "不公开"
homeDescription: "仅发送至首页的时间线"
followers: "仅关注者"
followersDescription: "仅发送至关注者"
@ -1395,6 +1441,7 @@ _timelines:
local: "本地"
social: "社交"
global: "全局"
recommended: 推荐
_pages:
newPage: "创建页面"
editPage: "编辑页面"
@ -1733,9 +1780,9 @@ _deck:
stackLeft: "向左折叠"
popRight: "向右弹出"
profile: "配置文件"
newProfile: "新建配置文件"
newProfile: "新建工作区"
renameProfile: "重命名配置文件"
deleteProfile: "删除配置文件"
deleteProfile: "删除工作区"
nameAlreadyExists: "该配置文件名已存在。"
introduction: "将各列进行组合以创建您自己的界面!"
introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
@ -1748,4 +1795,134 @@ _deck:
antenna: "天线"
list: "列表"
mentions: "提及"
direct: "指定用户"
direct: "私信"
channel: 频道
apps: 应用
_messaging:
dms: 私信
groups: 群组
migration: 迁移
_experiments:
title: 实验性功能
license: 许可证
flagSpeakAsCatDescription: 在猫模式下你的帖子会喵化
allowedInstances: 白名单服务器
listsDesc: 列表可以让你创建含有指定用户的时间线,它们可以从时间线页面访问。
flagSpeakAsCat: 像猫一样说话
removeReaction: 移除你的回应
expandOnNoteClick: 点击打开帖子
expandOnNoteClickDesc: 如果禁用,你仍然可以在右键菜单中或通过点击时间戳打开帖子。
sendPushNotificationReadMessage: 删除已阅读的推送通知
customMOTD: 自定义 MOTD闪屏消息
sendPushNotificationReadMessageCaption: 短暂显示 "{emptyPushNotificationMessage}" 的通知,如果启用,可能会增加你的设备的耗电量。
adminCustomCssWarn: 仅当你知道此设置的作用时才应使用它。输入不正确的值可能会导致每个人的客户端停止正常运行。请在用户设置中进行测试来确保您的 CSS
正常工作。
customMOTDDescription: 自定义MOTD闪屏消息一行一个每次用户加载/刷新页面时都会随机显示。
customSplashIconsDescription: 用换行符隔开的自定义闪屏图标的URL在用户每次加载/重新加载页面时随机显示。请确保图片是在一个静态的
URL 上,最好全部调整为 192x192 的大小。
recommendedInstancesDescription: 推荐的服务器以换行符分隔,它们将出现在推荐的时间线中。不要添加 "https://",仅添加域名。
splash: 启动画面
showUpdates: Calckey 更新后显示弹出窗口
selectInstance: 选择一个服务器
silencedInstances: 静默的服务器
antennaInstancesDescription: 每行列出一个服务器主机
pushNotification: 推送通知
subscribePushNotification: 启用推送通知
showAdminUpdates: 提示新的 Calckey 版本可用(仅对于管理员)
searchPlaceholder: 搜索 Calckey
addInstance: 添加一个服务器
jumpToPrevious: 跳转至上一个
silenceThisInstance: 使此服务器静音
manageGroups: 管理群组
antennasDesc: "天线会显示符合您设置条件的新帖子!\n可以从时间线页面访问它们。"
channelFederationWarn: 频道还没有与其他服务器联合
seperateRenoteQuote: 单独的推荐和引用按钮
customSplashIcons: 自定义闪屏图标urls
alt: 替代文字
pushNotificationNotSupported: 你的浏览器或者服务器不支持推送通知
showAds: 显示广告
enterSendsMessage: 按回车键发送信息(关闭则是 Ctrl + Retun
recommendedInstances: 推荐服务器
updateAvailable: 可能有可用更新!
swipeOnMobile: 允许在页面之间滑动
swipeOnDesktop: 允许在桌面端以移动设备方式滑动
logoImageUrl: Logo 图像 URL
deleted: 已删除
editNote: 编辑帖子
edited: 于 {date} {time} 编辑
selectChannel: 选择一个频道
accountMoved: 用户已迁移至新账户:
silencedInstancesDescription: 列出你想静默的服务器的主机名。列出的服务器中的账户被视为 "静默",只能发出跟随请求,如果不被跟随,就不能提及本地账户。这不会影响被封锁的服务器。
hiddenTags: 隐藏的哈希标签
userSaysSomethingReason: '{name} 说 {reason}'
clipsDesc: 便签就像可共享的分类书签。您可以从各个帖子的菜单中创建便签。
privateModeInfo: 当启用时,只有白名单上的服务器可以与你的服务器联合,所有的帖子都会对公共时间线隐藏。
allowedInstancesDescription: 要列入联合白名单的服务器的主机名,一行一个(仅适用于私密模式)。
breakFollowConfirm: 你确定要移除关注者吗?
caption: 自动显示说明文字
newer: 更新的
older: 更老的
noInstances: 没有服务器
silenced: 静默的
accessibility: 无障碍
secureMode: 安全模式(仅允许授权的拉取)
replayTutorial: 重播教程
userSaysSomethingReasonReply: '{name} 回复了包含 {reason} 的帖子'
userSaysSomethingReasonQuote: '{name} 引用了一篇包含 {reason} 的帖子'
userSaysSomethingReasonRenote: '{name} 推荐了一个包含 {reason} 的帖子'
noThankYou: 不,谢谢
secureModeInfo: 当向其他服务器请求时,不要在没有验证的情况下发回。
privateMode: 私密模式
instanceSecurity: 服务器安全
image: 图像
video: 视频
audio: 音频
cannotUploadBecauseExceedsFileSizeLimit: 无法上传此文件,因为它超出了允许的最大大小。
unsubscribePushNotification: 禁用推送通知
pushNotificationAlreadySubscribed: 推送通知已启用
enableEmojiReactions: 启用 emoji 回应
cw: 内容警告
hiddenTagsDescription: 列出你想隐藏的话题标签(不带#)以避免在趋势和探索中显示。隐藏的标签仍然可以通过其他方式被发现。
enableRecommendedTimeline: 启用推荐时间线
_skinTones:
medium: 中等
light: 浅色
yellow: 黄色
dark: 深色
isModerator: 协作者
isAdmin: 管理员
findOtherInstance: 寻找其它服务器
moveFromDescription: 这将为您的旧帐户设置一个别名,以便您可以从该旧帐户转移到当前帐户。在从旧帐户转移之前执行此操作。请输入格式如@person@server.com
的帐户标签
indexPosts: 索引帖子
signupsDisabled: 该服务器目前关闭注册,但您随时可以在另一台服务器上注册!如果您有该服务器的邀请码,请在下面输入。
silencedWarning: 显示这个页面是因为这些用户来自你的管理员设置的静默服务器,所以他们有可能是垃圾信息。
isBot: 这个账户是一个机器人
moveAccountDescription: 这个过程是不可逆的。在移动之前,请确保您已在新帐户上为当前帐户设置了别名。请输入格式如 @person@server.com
帐户标签
moveFromLabel: 您要移出的旧帐户:
preventAiLearning: 阻止 AI 机器人抓取
preventAiLearningDescription: 请求第三方人工智能语言模型不要研究您上传的内容,例如帖子和图像。
noGraze: 请禁用 "Graze for Mastodon" 浏览器扩展,因为它会干扰 Calckey。
moveTo: 将当前帐户移至新帐户
moveToLabel: 你要迁移到的目标帐户:
moveAccount: 移动账户!
migrationConfirm: "你确实确定要将帐户迁移到 {account} 吗?此操作无法撤消,并且你将无法再次正常使用旧账户。\n另外请确保你已将此当前帐户设置为要移出的帐户。"
indexFromDescription: 留空以索引每个帖子
noteId: 帖子 ID
moveFrom: 从旧帐户移至此帐户
defaultReaction: 发出和收到的帖子的默认表情符号反应
indexNotice: 现在开始索引。这可能需要一段时间,请至少一个小时内不要重新启动服务器。
indexFrom: 从帖子 ID 开始的索引
sendModMail: 发送审核通知
isLocked: 该帐户设置了关注请求
_filters:
notesBefore: 在之前的帖子
followingOnly: 仅关注中
notesAfter: 在之后的帖子
fromDomain: 来自域名
withFile: 带有文件
fromUser: 来自用户
followersOnly: 仅关注者
reactionPickerSkinTone: 首选的表情符号肤色
isPatron: Calckey 赞助

View file

@ -1816,7 +1816,6 @@ silenceThisInstance: 靜音此伺服器
silencedInstances: 已靜音的伺服器
silenced: 已靜音
_experiments:
enablePostEditing: 啟用帖子編輯
title: 試驗功能
findOtherInstance: 找找另一個伺服器
noGraze: 瀏覽器擴展 "Graze for Mastodon" 會與Calckey發生衝突請停用該擴展。

View file

@ -13,18 +13,19 @@ pub enum IdConvertType {
#[napi]
pub fn convert_id(in_id: String, id_convert_type: IdConvertType) -> napi::Result<String> {
println!("converting id: {}", in_id);
use IdConvertType::*;
match id_convert_type {
MastodonId => {
let mut out: i64 = 0;
let mut out: i128 = 0;
for (i, c) in in_id.to_lowercase().chars().rev().enumerate() {
out += num_from_char(c)? as i64 * 36_i64.pow(i as u32);
out += num_from_char(c)? as i128 * 36_i128.pow(i as u32);
}
Ok(out.to_string())
}
CalckeyId => {
let mut input: i64 = match in_id.parse() {
let mut input: i128 = match in_id.parse() {
Ok(s) => s,
Err(_) => {
return Err(Error::new(

View file

@ -43,7 +43,6 @@
"ajv": "8.12.0",
"archiver": "5.3.1",
"argon2": "^0.30.3",
"async-mutex": "^0.4.0",
"autobind-decorator": "2.4.0",
"autolinker": "4.0.0",
"autwh": "0.1.0",
@ -112,6 +111,7 @@
"ratelimiter": "3.4.1",
"re2": "1.19.0",
"redis-lock": "0.1.4",
"redis-semaphore": "5.3.1",
"reflect-metadata": "0.1.13",
"rename": "1.0.4",
"rndstr": "1.0.0",

View file

@ -1,42 +1,48 @@
import probeImageSize from "probe-image-size";
import { Mutex, withTimeout } from "async-mutex";
import { Mutex } from "redis-semaphore";
import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
import Logger from "@/services/logger.js";
import { Cache } from "./cache.js";
import { redisClient } from "@/db/redis.js";
export type Size = {
width: number;
height: number;
};
const cache = new Cache<boolean>(1000 * 60 * 10); // once every 10 minutes for the same url
const mutex = withTimeout(new Mutex(), 1000);
export async function getEmojiSize(url: string): Promise<Size> {
const logger = new Logger("emoji");
await mutex.runExclusive(() => {
const attempted = cache.get(url);
export async function getEmojiSize(url: string): Promise<Size> {
let attempted = true;
const lock = new Mutex(redisClient, "getEmojiSize");
await lock.acquire();
try {
const key = `getEmojiSize:${url}`;
attempted = (await redisClient.get(key)) !== null;
if (!attempted) {
cache.set(url, true);
} else {
logger.warn(`Attempt limit exceeded: ${url}`);
throw new Error("Too many attempts");
await redisClient.set(key, "done", "EX", 60 * 10);
}
} finally {
await lock.release();
}
if (attempted) {
logger.warn(`Attempt limit exceeded: ${url}`);
throw new Error("attempt limit exceeded");
}
});
try {
logger.info(`Retrieving emoji size from ${url}`);
logger.debug(`Retrieving emoji size from ${url}`);
const { width, height, mime } = await probeImageSize(url, {
timeout: 5000,
});
if (!(mime.startsWith("image/") && FILE_TYPE_BROWSERSAFE.includes(mime))) {
throw new Error("Unsupported image type");
throw new Error("unsupported image type");
}
return { width, height };
} catch (e) {
throw new Error(`Unable to retrieve metadata: ${e}`);
throw new Error(`unable to retrieve metadata: ${e}`);
}
}

View file

@ -482,7 +482,8 @@ export function createCleanRemoteFilesJob() {
export function createIndexAllNotesJob(data = {}) {
return backgroundQueue.add("indexAllNotes", data, {
removeOnComplete: true,
removeOnFail: true,
removeOnFail: false,
timeout: 1000 * 60 * 60 * 24,
});
}

View file

@ -20,7 +20,7 @@ export default async function indexAllNotes(
let total: number = (job.data.total as number) ?? 0;
let running = true;
const take = 50000;
const take = 100000;
const batch = 100;
while (running) {
logger.info(

View file

@ -541,10 +541,6 @@ function notEmpty(partial: Partial<any>) {
export async function updateNote(value: string | IObject, resolver?: Resolver) {
const uri = typeof value === "string" ? value : value.id;
if (!uri) throw new Error("Missing note uri");
const instanceMeta = await fetchMeta();
if (instanceMeta.experimentalFeatures?.postEdits === false) {
throw new Error("Post edits disabled.");
}
// Skip if URI points to this server
if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local");

View file

@ -476,9 +476,6 @@ export const meta = {
optional: true,
nullable: true,
properties: {
postEditing: {
type: "boolean",
},
postImports: {
type: "boolean",
},

View file

@ -174,7 +174,6 @@ export const paramDef = {
type: "object",
nullable: true,
properties: {
postEditing: { type: "boolean" },
postImports: { type: "boolean" },
},
},

View file

@ -529,7 +529,7 @@ export default define(meta, paramDef, async (ps, me) => {
github: instance.enableGithubIntegration,
discord: instance.enableDiscordIntegration,
serviceWorker: instance.enableServiceWorker,
postEditing: instance.experimentalFeatures?.postEditing || false,
postEditing: true,
postImports: instance.experimentalFeatures?.postImports || false,
miauth: true,
};

View file

@ -140,12 +140,6 @@ export const meta = {
code: "NOT_LOCAL_USER",
id: "b907f407-2aa0-4283-800b-a2c56290b822",
},
editsDisabled: {
message: "Post edits are disabled.",
code: "EDITS_DISABLED",
id: "99306f00-fb81-11ed-be56-0242ac120002",
},
},
} as const;
@ -244,11 +238,6 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => {
if (user.movedToUri != null) throw new ApiError(meta.errors.accountLocked);
const instanceMeta = await fetchMeta();
if (instanceMeta.experimentalFeatures?.postEdits === false) {
throw new ApiError(meta.errors.editsDisabled);
}
if (!Users.isLocalUser(user)) {
throw new ApiError(meta.errors.notLocalUser);
}

View file

@ -23,8 +23,15 @@ export default define(meta, paramDef, async (ps) => {
if (!ps.forceUpdate && cachedPatrons) {
patrons = JSON.parse(cachedPatrons);
} else {
AbortSignal.timeout ??= function timeout(ms) {
const ctrl = new AbortController()
setTimeout(() => ctrl.abort(), ms)
return ctrl.signal
}
patrons = await fetch(
"https://codeberg.org/calckey/calckey/raw/branch/develop/patrons.json",
{ signal: AbortSignal.timeout(2000) }
)
.then((response) => response.json())
.catch(() => {

View file

@ -83,7 +83,7 @@ const nodeinfo2 = async () => {
disableGlobalTimeline: meta.disableGlobalTimeline,
emailRequiredForSignup: meta.emailRequiredForSignup,
searchFilters: config.meilisearch ? true : false,
postEditing: meta.experimentalFeatures?.postEditing || false,
postEditing: true,
postImports: meta.experimentalFeatures?.postImports || false,
enableHcaptcha: meta.enableHcaptcha,
enableRecaptcha: meta.enableRecaptcha,

View file

@ -69,6 +69,7 @@ import { getActiveWebhooks } from "@/misc/webhook-cache.js";
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
import meilisearch from "../../db/meilisearch.js";
import { redisClient } from "@/db/redis.js";
import { Mutex } from "redis-semaphore";
const mutedWordsCache = new Cache<
{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
@ -461,58 +462,43 @@ export default async (
}
if (!dontFederateInitially) {
let publishKey: string;
let noteToPublish: Note;
const relays = await getCachedRelays();
// Some relays (e.g., aode-relay) deliver posts by boosting them as
// Announce activities. In that case, user is the relay's actor.
const boostedByRelay =
!!user.inbox &&
relays.map((relay) => relay.inbox).includes(user.inbox);
if (!note.uri) {
// Publish if the post is local
publishNotesStream(note);
} else if (boostedByRelay && data.renote?.uri) {
// Use Redis transaction for atomicity
await redisClient.watch(`publishedNote:${data.renote.uri}`);
const exists = await redisClient.exists(
`publishedNote:${data.renote.uri}`,
if (boostedByRelay && data.renote && data.renote.userHost) {
publishKey = `publishedNote:${data.renote.id}`;
noteToPublish = data.renote;
} else {
publishKey = `publishedNote:${note.id}`;
noteToPublish = note;
}
const lock = new Mutex(redisClient, "publishedNote");
await lock.acquire();
try {
const published = (await redisClient.get(publishKey)) !== null;
if (!published) {
await redisClient.set(publishKey, "done", "EX", 30);
if (noteToPublish.renoteId) {
// Prevents other threads from publishing the boosting post
await redisClient.set(
`publishedNote:${noteToPublish.renoteId}`,
"done",
"EX",
30,
);
if (exists === 0) {
// Start the transaction
const transaction = redisClient.multi();
const key = `publishedNote:${data.renote.uri}`;
transaction.set(key, 1, "EX", 30);
// Execute the transaction
transaction.exec((err, replies) => {
// Publish after setting the key in Redis
if (!err && data.renote) {
publishNotesStream(data.renote);
}
});
} else {
// Abort the transaction
redisClient.unwatch();
}
} else if (!boostedByRelay && note.uri) {
// Use Redis transaction for atomicity
await redisClient.watch(`publishedNote:${note.uri}`);
const exists = await redisClient.exists(`publishedNote:${note.uri}`);
if (exists === 0) {
// Start the transaction
const transaction = redisClient.multi();
const key = `publishedNote:${note.uri}`;
transaction.set(key, 1, "EX", 30);
// Execute the transaction
transaction.exec((err, replies) => {
// Publish after setting the key in Redis
if (!err) {
publishNotesStream(note);
}
});
} else {
// Abort the transaction
redisClient.unwatch();
publishNotesStream(noteToPublish);
}
} finally {
await lock.release();
}
}
if (note.replyId != null) {

View file

@ -67,9 +67,8 @@ function chosen(emoji: any) {
function opening() {
try {
picker.value?.reset();
}
catch (e) {
console.error(`Something's wrong with restting the emoji picker: ${e}`)
} catch (e) {
console.error(`Something's wrong with restting the emoji picker: ${e}`);
}
picker.value?.focus();
}

View file

@ -337,9 +337,7 @@ let appearNote = $computed(() =>
const isMyRenote = $i && $i.id === note.userId;
const showContent = ref(false);
const isDeleted = ref(false);
const muted = ref(
getWordSoftMute(appearNote, $i, defaultStore.state.mutedWords)
);
const muted = ref(getWordSoftMute(note, $i, defaultStore.state.mutedWords));
const translation = ref(null);
const translating = ref(false);
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;

View file

@ -53,12 +53,12 @@ const props = defineProps<{
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
function scrollTop() {
scroll(tlEl.value, { top: 0, behavior: 'smooth' })
scroll(tlEl.value, { top: 0, behavior: "smooth" });
}
defineExpose({
pagingComponent,
scrollTop
scrollTop,
});
</script>

View file

@ -23,7 +23,7 @@
ref="tlComponent"
:no-gap="!$store.state.showGapBetweenNotesInTimeline"
:pagination="pagination"
@queue="(x) => queue = x"
@queue="(x) => (queue = x)"
/>
</template>

View file

@ -97,13 +97,16 @@
><Mfm
:text="'$[sparkle @kainoa@calckey.social] (Main developer)'"
/></FormLink>
<FormLink to="/@april@calckey.social"
><Mfm :text="'@april@calckey.social (Backend)'"
/></FormLink>
<FormLink to="/@freeplay@calckey.social"
><Mfm
:text="'@freeplay@calckey.social (UI/UX)'"
/></FormLink>
<FormLink to="/@nmkj@calckey.jp"
><Mfm :text="'@nmkj@calckey.jp (Backend)'"
/></FormLink>
<FormLink to="/@dev@post.naskya.net"
><Mfm :text="'@dev@post.naskya.net (Backend)'"
/></FormLink>
<FormLink to="/@panos@calckey.social"
><Mfm
:text="'@panos@calckey.social (Project Coordinator)'"
@ -128,6 +131,9 @@
><Mfm text="$[jelly ❤]" />
{{ i18n.ts._aboutMisskey.patrons }}</template
>
<p>
{{ i18n.ts._aboutMisskey.patronsList }}
</p>
<MkSparkle>
<span
v-for="patron in patrons"
@ -164,7 +170,12 @@ import { defaultStore } from "@/store";
import * as os from "@/os";
import { definePageMetadata } from "@/scripts/page-metadata";
const patrons = await os.api("patrons", { forceUpdate: true });
let patrons = [];
try {
patrons = await os.api("patrons", { forceUpdate: true });
} catch {
console.error("Codeberg's down.")
}
let easterEggReady = false;
let easterEggEmojis = $ref([]);

View file

@ -8,19 +8,6 @@
/></template>
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
<FormSuspense :p="init">
<FormSwitch
v-model="enablePostEditing"
@update:modelValue="save"
class="_formBlock"
>
<template #label>
<i class="ph-pencil-line ph-bold ph-lg"></i>
{{ i18n.ts._experiments.enablePostEditing }}
</template>
<template #caption>{{
i18n.ts._experiments.postEditingCaption
}}</template>
</FormSwitch>
<FormSwitch
v-model="enablePostImports"
@update:modelValue="save"
@ -49,13 +36,11 @@ import { fetchInstance } from "@/instance";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata";
let enablePostEditing = $ref(false);
let enablePostImports = $ref(false);
let meta = $ref<MetaExperiments | null>(null);
type MetaExperiments = {
experimentalFeatures?: {
postEditing?: boolean;
postImports?: boolean;
};
};
@ -64,14 +49,12 @@ async function init() {
meta = (await os.api("admin/meta")) as MetaExperiments;
if (!meta) return;
enablePostEditing = meta.experimentalFeatures?.postEditing ?? false;
enablePostImports = meta.experimentalFeatures?.postImports ?? false;
}
function save() {
const experiments: MetaExperiments = {
experimentalFeatures: {
postEditing: enablePostEditing,
postImports: enablePostImports,
},
};

View file

@ -22,7 +22,7 @@
:value="usersComparedToThePrevDay"
></MkNumberDiff>
</div>
<div class="label">Users</div>
<div class="label">{{ i18n.ts.users }}</div>
</div>
</div>
<div class="item _panel notes">
@ -41,7 +41,7 @@
:value="notesComparedToThePrevDay"
></MkNumberDiff>
</div>
<div class="label">Posts</div>
<div class="label">{{ i18n.ts.notes }}</div>
</div>
</div>
<div class="item _panel instances">
@ -55,7 +55,7 @@
style="margin-right: 0.5em"
/>
</div>
<div class="label">Instances</div>
<div class="label">{{ i18n.ts.instances }}</div>
</div>
</div>
<div class="item _panel online">
@ -69,10 +69,26 @@
style="margin-right: 0.5em"
/>
</div>
<div class="label">Online</div>
<div class="label">{{ i18n.ts.online }}</div>
</div>
</div>
<div class="item _panel emojis">
<div class="icon">
<i class="ph-smiley ph-bold ph-xl"></i>
</div>
<div class="body">
<div class="value">
<MkNumber
:value="emojiCount"
style="margin-right: 0.5em"
/>
</div>
<div class="label">{{ i18n.ts.emojis }}</div>
</div>
</div>
</div>
<!-- TODO: Drive -->
</Transition>
</div>
</template>
@ -90,6 +106,7 @@ let stats: any = $ref(null);
let usersComparedToThePrevDay = $ref<number>();
let notesComparedToThePrevDay = $ref<number>();
let onlineUsersCount = $ref(0);
let emojiCount = $ref(0);
let fetching = $ref(true);
onMounted(async () => {
@ -110,6 +127,10 @@ onMounted(async () => {
stats.originalNotesCount - chart.local.total[1];
});
os.api("meta", { detail: false }).then((meta) => {
emojiCount = meta.emojis.length;
});
fetching = false;
});
</script>
@ -172,6 +193,13 @@ onMounted(async () => {
}
}
&.drive {
> .icon {
background: #b4637a22;
color: #eb6f92;
}
}
> .body {
padding: 2px 0;

View file

@ -24,7 +24,9 @@
<div
ref="bannerEl"
class="banner"
:style="{ backgroundImage: `url('${user.bannerUrl}')` }"
:style="{
backgroundImage: `url('${user.bannerUrl}')`,
}"
></div>
<div class="fade"></div>
<div class="title">
@ -449,7 +451,12 @@ const timeForThem = $computed(() => {
return "";
});
const patrons = await os.api("patrons");
let patrons = [];
try {
patrons = await os.api("patrons");
} catch {
console.error("Codeberg's down.")
}
function parallaxLoop() {
parallaxAnimationId = window.requestAnimationFrame(parallaxLoop);
@ -510,7 +517,7 @@ onUnmounted(() => {
background-size: cover;
background-position: center;
pointer-events: none;
filter: blur(12px) opacity(.1);
filter: blur(12px) opacity(0.1);
}
}

View file

@ -408,7 +408,7 @@ export function getNoteMenu(props: {
},
}
: undefined,
instance.features.postEditing && isAppearAuthor
isAppearAuthor
? {
icon: "ph-pencil-line ph-bold ph-lg",
text: i18n.ts.edit,

View file

@ -5,7 +5,7 @@
<span class="year">{{ i18n.t("yearX", { year }) }}</span>
<span class="month">{{ i18n.t("monthX", { month }) }}</span>
</p>
<p v-if="month === 1 && day === 1" class="day">
<p v-if="(month === 1 && day === 1) || isBirthday" class="day">
🎉{{ i18n.t("dayX", { day })
}}<span style="display: inline-block; transform: scaleX(-1)"
>🎉</span
@ -55,6 +55,7 @@ import {
import { GetFormResultType } from "@/scripts/form";
import { i18n } from "@/i18n";
import { useInterval } from "@/scripts/use-interval";
import { $i } from "@/account";
const name = "calendar";
@ -80,6 +81,8 @@ const { widgetProps, configure } = useWidgetPropsManager(
emit
);
const hasBirthday = Boolean($i?.birthday);
const year = ref(0);
const month = ref(0);
const day = ref(0);
@ -88,6 +91,8 @@ const yearP = ref(0);
const monthP = ref(0);
const dayP = ref(0);
const isHoliday = ref(false);
const isBirthday = ref(false);
const tick = () => {
const now = new Date();
const nd = now.getDate();
@ -121,6 +126,13 @@ const tick = () => {
yearP.value = (yearNumer / yearDenom) * 100;
isHoliday.value = now.getDay() === 0 || now.getDay() === 6;
if (hasBirthday) {
const [bdayYear, bdayMonth, bdayDay] = $i.birthday.split("-");
if (month.value === +bdayMonth && day.value == +bdayDay) {
isBirthday.value = true;
}
}
};
useInterval(tick, 1000, {

View file

@ -10,17 +10,15 @@
"@griff@stop.voring.me",
"@cafkafk@ck.cafkafk.com",
"@privateger@plasmatrap.com",
"@self@neo.voidworks.cc",
"@effy@social.effy.space",
"@effye@toot.thoughtworks.com",
"@Kio@kitsunes.club",
"@twann@tech.lgbt",
"@surfbum@calckey.nz",
"@topher@mastodon.online",
"@hanicef@stop.voring.me",
"@nmkj@calckey.jp",
"@trapezial@calckey.jp",
"@unattributed@calckey.social",
"@cody@mk.codingneko.com",
"@cody@misskey.codingneko.com",
"@kate@blahaj.zone",
"@emtk@mkkey.net",
"@jovikowi@calckey.social",
@ -35,13 +33,12 @@
"@box464@calckey.social",
"@MariaTheMartian@calckey.social",
"@nisemikol@calckey.social",
"@smallpatatas@calckey.patatas.ca",
"@smallpatatas@blahaj.zone",
"@bayra@stop.voring.me",
"@frost@wolfdo.gg",
"@joebiden@fuckgov.org",
"@nyaa@calckey.social",
"@Dan@calckey.social",
"@testing@stop.voring.me",
"@dana@calckey.social",
"@Jdreben@calckey.social",
"@natalie@prismst.one",
@ -77,6 +74,10 @@
"@jtbennett@noc.social",
"@renere@distance.blue",
"@theking@kitsunes.club",
"@toof@fedi.toofie.net",
"@Punko@calckey.social",
"@joesbrat67@calckey.social",
"@arth@calckey.social",
"\nInterkosmos Link"
]
}

View file

@ -132,9 +132,6 @@ importers:
argon2:
specifier: ^0.30.3
version: 0.30.3
async-mutex:
specifier: ^0.4.0
version: 0.4.0
autobind-decorator:
specifier: 2.4.0
version: 2.4.0
@ -339,6 +336,9 @@ importers:
redis-lock:
specifier: 0.1.4
version: 0.1.4
redis-semaphore:
specifier: 5.3.1
version: 5.3.1(ioredis@5.3.2)
reflect-metadata:
specifier: 0.1.13
version: 0.1.13
@ -598,7 +598,7 @@ importers:
version: 5.1.3
webpack:
specifier: ^5.85.1
version: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3)
version: 5.85.1(@swc/core@1.3.62)
ws:
specifier: 8.13.0
version: 8.13.0
@ -2666,6 +2666,7 @@ packages:
engines: {node: '>=10'}
cpu: [arm64]
os: [android]
requiresBuild: true
dependencies:
'@swc/wasm': 1.2.130
@ -2772,6 +2773,7 @@ packages:
/@swc/wasm@1.2.130:
resolution: {integrity: sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==}
requiresBuild: true
/@syuilo/aiscript@0.11.1:
resolution: {integrity: sha512-chwOIA3yLUKvOB0G611hjLArKTeOWNmTm3lHERSaDW1d+dS6do56naX6Lkwy2UpnwWC0qzeNSgg35elk6t2gZg==}
@ -4491,12 +4493,6 @@ packages:
stream-exhaust: 1.0.2
dev: true
/async-mutex@0.4.0:
resolution: {integrity: sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==}
dependencies:
tslib: 2.6.0
dev: false
/async-settle@1.0.0:
resolution: {integrity: sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==}
engines: {node: '>= 0.10'}
@ -4641,7 +4637,7 @@ packages:
/axios@0.24.0:
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
dependencies:
follow-redirects: 1.15.2(debug@4.3.4)
follow-redirects: 1.15.2
transitivePeerDependencies:
- debug
dev: false
@ -4657,7 +4653,7 @@ packages:
/axios@1.2.2:
resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==}
dependencies:
follow-redirects: 1.15.2(debug@4.3.4)
follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@ -4667,7 +4663,7 @@ packages:
/axios@1.4.0:
resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==}
dependencies:
follow-redirects: 1.15.2(debug@4.3.4)
follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@ -6283,6 +6279,17 @@ packages:
dependencies:
ms: 2.0.0
/debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.3
dev: false
/debug@3.2.7(supports-color@8.1.1):
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
@ -6293,6 +6300,7 @@ packages:
dependencies:
ms: 2.1.3
supports-color: 8.1.1
dev: true
/debug@4.3.3:
resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
@ -7530,6 +7538,16 @@ packages:
tabbable: 6.2.0
dev: true
/follow-redirects@1.15.2:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dev: false
/follow-redirects@1.15.2(debug@4.3.4):
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
@ -7540,6 +7558,7 @@ packages:
optional: true
dependencies:
debug: 4.3.4(supports-color@8.1.1)
dev: true
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@ -8450,7 +8469,7 @@ packages:
engines: {node: '>= 4.5.0'}
dependencies:
agent-base: 4.3.0
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
transitivePeerDependencies:
- supports-color
dev: false
@ -9849,7 +9868,7 @@ packages:
json5: 2.2.3
loader-utils: 2.0.4
schema-utils: 3.3.0
webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3)
webpack: 5.85.1(@swc/core@1.3.62)
dev: true
/json5@2.2.3:
@ -10092,7 +10111,7 @@ packages:
resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==}
engines: {node: '>= 7.6.0'}
dependencies:
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
koa-send: 5.0.1
transitivePeerDependencies:
- supports-color
@ -11086,7 +11105,7 @@ packages:
engines: {node: '>= 4.4.x'}
hasBin: true
dependencies:
debug: 3.2.7(supports-color@8.1.1)
debug: 3.2.7
iconv-lite: 0.4.24
sax: 1.2.4
transitivePeerDependencies:
@ -12831,6 +12850,18 @@ packages:
dependencies:
redis-errors: 1.2.0
/redis-semaphore@5.3.1(ioredis@5.3.2):
resolution: {integrity: sha512-oUpxxfxSbh5eT0mvVpz2d4Qlg2CsaoQkeo80/v6CU2l97zO0u6NPgc9/zQZa9KGR3/93b0igtSct3hEFh8Ei8w==}
engines: {node: '>= 14.17.0'}
peerDependencies:
ioredis: ^4.1.0 || ^5
dependencies:
debug: 4.3.4(supports-color@8.1.1)
ioredis: 5.3.2
transitivePeerDependencies:
- supports-color
dev: false
/redis@4.6.7:
resolution: {integrity: sha512-KrkuNJNpCwRm5vFJh0tteMxW8SaUzkm5fBH7eL5hd/D0fAkzvapxbfGPP/r+4JAXdQuX7nebsBkBqA2RHB7Usw==}
dependencies:
@ -13980,7 +14011,7 @@ packages:
webpack: '>=2'
dependencies:
'@swc/core': 1.3.62
webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3)
webpack: 5.85.1(@swc/core@1.3.62)
dev: true
/swiper@9.3.2:
@ -14101,7 +14132,7 @@ packages:
schema-utils: 3.3.0
serialize-javascript: 6.0.1
terser: 5.18.2
webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3)
webpack: 5.85.1(@swc/core@1.3.62)
dev: true
/terser@5.18.2:
@ -14401,7 +14432,7 @@ packages:
micromatch: 4.0.5
semver: 7.5.1
typescript: 5.1.3
webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3)
webpack: 5.85.1(@swc/core@1.3.62)
dev: true
/ts-node@10.4.0(@swc/core@1.3.62)(@types/node@20.3.1)(typescript@5.1.3):
@ -15235,6 +15266,46 @@ packages:
engines: {node: '>=10.13.0'}
dev: true
/webpack@5.85.1(@swc/core@1.3.62):
resolution: {integrity: sha512-xTb7MRf4LY8Z5rzn7aIx4TDrwYJrjcHnIfU1TqtyZOoObyuGSpAUwIvVuqq5wPnv7WEgQr8UvO1q/dgoGG4HjA==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
webpack-cli: '*'
peerDependenciesMeta:
webpack-cli:
optional: true
dependencies:
'@types/eslint-scope': 3.7.4
'@types/estree': 1.0.1
'@webassemblyjs/ast': 1.11.6
'@webassemblyjs/wasm-edit': 1.11.6
'@webassemblyjs/wasm-parser': 1.11.6
acorn: 8.9.0
acorn-import-assertions: 1.9.0(acorn@8.9.0)
browserslist: 4.21.9
chrome-trace-event: 1.0.3
enhanced-resolve: 5.15.0
es-module-lexer: 1.3.0
eslint-scope: 5.1.1
events: 3.3.0
glob-to-regexp: 0.4.1
graceful-fs: 4.2.11
json-parse-even-better-errors: 2.3.1
loader-runner: 4.3.0
mime-types: 2.1.35
neo-async: 2.6.2
schema-utils: 3.3.0
tapable: 2.2.1
terser-webpack-plugin: 5.3.9(@swc/core@1.3.62)(webpack@5.85.1)
watchpack: 2.4.0
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
dev: true
/webpack@5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3):
resolution: {integrity: sha512-xTb7MRf4LY8Z5rzn7aIx4TDrwYJrjcHnIfU1TqtyZOoObyuGSpAUwIvVuqq5wPnv7WEgQr8UvO1q/dgoGG4HjA==}
engines: {node: '>=10.13.0'}