Compare commits
4 Commits
534655c66d
...
b58917aabb
Author | SHA1 | Date |
---|---|---|
Natty | b58917aabb | |
Natty | 16e0a1ae22 | |
Natty | 1a95418fef | |
Natty | c5987de47e |
|
@ -1,25 +0,0 @@
|
||||||
// AID
|
|
||||||
// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ2の[ノイズ文字列]
|
|
||||||
|
|
||||||
import * as crypto from "node:crypto";
|
|
||||||
|
|
||||||
const TIME2000 = 946684800000;
|
|
||||||
let counter = crypto.randomBytes(2).readUInt16LE(0);
|
|
||||||
|
|
||||||
function getTime(time: number) {
|
|
||||||
time = time - TIME2000;
|
|
||||||
if (time < 0) time = 0;
|
|
||||||
|
|
||||||
return time.toString(36).padStart(8, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNoise() {
|
|
||||||
return counter.toString(36).padStart(2, "0").slice(-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function genAid(date: Date): string {
|
|
||||||
const t = date.getTime();
|
|
||||||
if (isNaN(t)) throw "Failed to create AID: Invalid Date";
|
|
||||||
counter++;
|
|
||||||
return getTime(t) + getNoise();
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
const CHARS = "0123456789abcdef";
|
|
||||||
|
|
||||||
function getTime(time: number) {
|
|
||||||
if (time < 0) time = 0;
|
|
||||||
if (time === 0) {
|
|
||||||
return CHARS[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
time += 0x800000000000;
|
|
||||||
|
|
||||||
return time.toString(16).padStart(12, CHARS[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRandom() {
|
|
||||||
let str = "";
|
|
||||||
|
|
||||||
for (let i = 0; i < 12; i++) {
|
|
||||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function genMeid(date: Date): string {
|
|
||||||
return getTime(date.getTime()) + getRandom();
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
const CHARS = "0123456789abcdef";
|
|
||||||
|
|
||||||
// 4bit Fixed hex value 'g'
|
|
||||||
// 44bit UNIX Time ms in Hex
|
|
||||||
// 48bit Random value in Hex
|
|
||||||
|
|
||||||
function getTime(time: number) {
|
|
||||||
if (time < 0) time = 0;
|
|
||||||
if (time === 0) {
|
|
||||||
return CHARS[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.toString(16).padStart(11, CHARS[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRandom() {
|
|
||||||
let str = "";
|
|
||||||
|
|
||||||
for (let i = 0; i < 12; i++) {
|
|
||||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function genMeidg(date: Date): string {
|
|
||||||
return `g${getTime(date.getTime())}${getRandom()}`;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
const CHARS = "0123456789abcdef";
|
|
||||||
|
|
||||||
function getTime(time: number) {
|
|
||||||
if (time < 0) time = 0;
|
|
||||||
if (time === 0) {
|
|
||||||
return CHARS[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
time = Math.floor(time / 1000);
|
|
||||||
|
|
||||||
return time.toString(16).padStart(8, CHARS[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRandom() {
|
|
||||||
let str = "";
|
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function genObjectId(date: Date): string {
|
|
||||||
return getTime(date.getTime()) + getRandom();
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Prelude
|
|
||||||
このディレクトリのコードはJavaScriptの表現能力を補うためのコードです。
|
|
||||||
Misskey固有の処理とは独立したコードの集まりですが、Misskeyのコードを読みやすくすることを目的としています。
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { EndoRelation, Predicate } from "./relation.js";
|
import type {Predicate} from "./relation.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the number of elements that satisfy the predicate
|
* Count the number of elements that satisfy the predicate
|
||||||
|
@ -30,21 +30,6 @@ export function intersperse<T>(sep: T, xs: T[]): T[] {
|
||||||
return concat(xs.map((x) => [sep, x])).slice(1);
|
return concat(xs.map((x) => [sep, x])).slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the array of elements that is not equal to the element
|
|
||||||
*/
|
|
||||||
export function erase<T>(a: T, xs: T[]): T[] {
|
|
||||||
return xs.filter((x) => x !== a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the array of all elements in the first array not contained in the second array.
|
|
||||||
* The order of result values are determined by the first array.
|
|
||||||
*/
|
|
||||||
export function difference<T>(xs: T[], ys: T[]): T[] {
|
|
||||||
return xs.filter((x) => !ys.includes(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all but the first element from every group of equivalent elements
|
* Remove all but the first element from every group of equivalent elements
|
||||||
*/
|
*/
|
||||||
|
@ -60,75 +45,6 @@ export function maximum(xs: number[]): number {
|
||||||
return Math.max(...xs);
|
return Math.max(...xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Splits an array based on the equivalence relation.
|
|
||||||
* The concatenation of the result is equal to the argument.
|
|
||||||
*/
|
|
||||||
export function groupBy<T>(f: EndoRelation<T>, xs: T[]): T[][] {
|
|
||||||
const groups = [] as T[][];
|
|
||||||
for (const x of xs) {
|
|
||||||
if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) {
|
|
||||||
groups[groups.length - 1].push(x);
|
|
||||||
} else {
|
|
||||||
groups.push([x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splits an array based on the equivalence relation induced by the function.
|
|
||||||
* The concatenation of the result is equal to the argument.
|
|
||||||
*/
|
|
||||||
export function groupOn<T, S>(f: (x: T) => S, xs: T[]): T[][] {
|
|
||||||
return groupBy((a, b) => f(a) === f(b), xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function groupByX<T>(collections: T[], keySelector: (x: T) => string) {
|
|
||||||
return collections.reduce((obj: Record<string, T[]>, item: T) => {
|
|
||||||
const key = keySelector(item);
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
||||||
obj[key] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
obj[key].push(item);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare two arrays by lexicographical order
|
|
||||||
*/
|
|
||||||
export function lessThan(xs: number[], ys: number[]): boolean {
|
|
||||||
for (let i = 0; i < Math.min(xs.length, ys.length); i++) {
|
|
||||||
if (xs[i] < ys[i]) return true;
|
|
||||||
if (xs[i] > ys[i]) return false;
|
|
||||||
}
|
|
||||||
return xs.length < ys.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the longest prefix of elements that satisfy the predicate
|
|
||||||
*/
|
|
||||||
export function takeWhile<T>(f: Predicate<T>, xs: T[]): T[] {
|
|
||||||
const ys = [];
|
|
||||||
for (const x of xs) {
|
|
||||||
if (f(x)) {
|
|
||||||
ys.push(x);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ys;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cumulativeSum(xs: number[]): number[] {
|
|
||||||
const ys = Array.from(xs); // deep copy
|
|
||||||
for (let i = 1; i < ys.length; i++) ys[i] += ys[i - 1];
|
|
||||||
return ys;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toArray<T>(x: T | T[] | undefined): T[] {
|
export function toArray<T>(x: T | T[] | undefined): T[] {
|
||||||
return Array.isArray(x) ? x : x != null ? [x] : [];
|
return Array.isArray(x) ? x : x != null ? [x] : [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
export function gcd(a: number, b: number): number {
|
|
||||||
return b === 0 ? a : gcd(b, a % b);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
export interface IMaybe<T> {
|
|
||||||
isJust(): this is IJust<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IJust<T> extends IMaybe<T> {
|
|
||||||
get(): T;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function just<T>(value: T): IJust<T> {
|
|
||||||
return {
|
|
||||||
isJust: () => true,
|
|
||||||
get: () => value,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nothing<T>(): IMaybe<T> {
|
|
||||||
return {
|
|
||||||
isJust: () => false,
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,5 +1 @@
|
||||||
export type Predicate<T> = (a: T) => boolean;
|
export type Predicate<T> = (a: T) => boolean;
|
||||||
|
|
||||||
export type Relation<T, U> = (a: T, b: U) => boolean;
|
|
||||||
|
|
||||||
export type EndoRelation<T> = Relation<T, T>;
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
export function concat(xs: string[]): string {
|
|
||||||
return xs.join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function capitalize(s: string): string {
|
|
||||||
return toUpperCase(s.charAt(0)) + toLowerCase(s.slice(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toUpperCase(s: string): string {
|
|
||||||
return s.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toLowerCase(s: string): string {
|
|
||||||
return s.toLowerCase();
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
export const fallback = Symbol("fallback");
|
|
|
@ -32,7 +32,8 @@ import * as ep___admin_emoji_setCategoryBulk from "./endpoints/admin/emoji/set-c
|
||||||
import * as ep___admin_emoji_setLicenseBulk from "./endpoints/admin/emoji/set-license-bulk.js";
|
import * as ep___admin_emoji_setLicenseBulk from "./endpoints/admin/emoji/set-license-bulk.js";
|
||||||
import * as ep___admin_emoji_update from "./endpoints/admin/emoji/update.js";
|
import * as ep___admin_emoji_update from "./endpoints/admin/emoji/update.js";
|
||||||
import * as ep___admin_federation_deleteAllFiles from "./endpoints/admin/federation/delete-all-files.js";
|
import * as ep___admin_federation_deleteAllFiles from "./endpoints/admin/federation/delete-all-files.js";
|
||||||
import * as ep___admin_federation_refreshRemoteInstanceMetadata from "./endpoints/admin/federation/refresh-remote-instance-metadata.js";
|
import * as ep___admin_federation_refreshRemoteInstanceMetadata
|
||||||
|
from "./endpoints/admin/federation/refresh-remote-instance-metadata.js";
|
||||||
import * as ep___admin_federation_removeAllFollowing from "./endpoints/admin/federation/remove-all-following.js";
|
import * as ep___admin_federation_removeAllFollowing from "./endpoints/admin/federation/remove-all-following.js";
|
||||||
import * as ep___admin_federation_updateInstance from "./endpoints/admin/federation/update-instance.js";
|
import * as ep___admin_federation_updateInstance from "./endpoints/admin/federation/update-instance.js";
|
||||||
import * as ep___admin_getIndexStats from "./endpoints/admin/get-index-stats.js";
|
import * as ep___admin_getIndexStats from "./endpoints/admin/get-index-stats.js";
|
||||||
|
@ -283,7 +284,6 @@ import * as ep___pinnedUsers from "./endpoints/pinned-users.js";
|
||||||
import * as ep___customMOTD from "./endpoints/custom-motd.js";
|
import * as ep___customMOTD from "./endpoints/custom-motd.js";
|
||||||
import * as ep___customSplashIcons from "./endpoints/custom-splash-icons.js";
|
import * as ep___customSplashIcons from "./endpoints/custom-splash-icons.js";
|
||||||
import * as ep___latestVersion from "./endpoints/latest-version.js";
|
import * as ep___latestVersion from "./endpoints/latest-version.js";
|
||||||
import * as ep___patrons from "./endpoints/patrons.js";
|
|
||||||
import * as ep___release from "./endpoints/release.js";
|
import * as ep___release from "./endpoints/release.js";
|
||||||
import * as ep___promo_read from "./endpoints/promo/read.js";
|
import * as ep___promo_read from "./endpoints/promo/read.js";
|
||||||
import * as ep___requestResetPassword from "./endpoints/request-reset-password.js";
|
import * as ep___requestResetPassword from "./endpoints/request-reset-password.js";
|
||||||
|
@ -631,7 +631,6 @@ const eps = [
|
||||||
["custom-motd", ep___customMOTD],
|
["custom-motd", ep___customMOTD],
|
||||||
["custom-splash-icons", ep___customSplashIcons],
|
["custom-splash-icons", ep___customSplashIcons],
|
||||||
["latest-version", ep___latestVersion],
|
["latest-version", ep___latestVersion],
|
||||||
["patrons", ep___patrons],
|
|
||||||
["release", ep___release],
|
["release", ep___release],
|
||||||
["promo/read", ep___promo_read],
|
["promo/read", ep___promo_read],
|
||||||
["request-reset-password", ep___requestResetPassword],
|
["request-reset-password", ep___requestResetPassword],
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import define from "../define.js";
|
|
||||||
import { redisClient } from "@/db/redis.js";
|
|
||||||
|
|
||||||
export const meta = {
|
|
||||||
tags: ["meta"],
|
|
||||||
description: "Get list of Calckey patrons from Codeberg",
|
|
||||||
|
|
||||||
requireCredential: false,
|
|
||||||
requireCredentialPrivateMode: false,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: "object",
|
|
||||||
properties: {},
|
|
||||||
required: [],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export default define(meta, paramDef, async () => {
|
|
||||||
let patrons;
|
|
||||||
const cachedPatrons = await redisClient.get("patrons");
|
|
||||||
if (cachedPatrons) {
|
|
||||||
patrons = JSON.parse(cachedPatrons);
|
|
||||||
} else {
|
|
||||||
patrons = await fetch(
|
|
||||||
"https://codeberg.org/calckey/calckey/raw/branch/develop/patrons.json",
|
|
||||||
).then((response) => response.json());
|
|
||||||
await redisClient.set("patrons", JSON.stringify(patrons), "EX", 3600);
|
|
||||||
}
|
|
||||||
|
|
||||||
return patrons["patrons"];
|
|
||||||
});
|
|
|
@ -1,41 +0,0 @@
|
||||||
import type { KVs } from "../core.js";
|
|
||||||
import Chart from "../core.js";
|
|
||||||
import { name, schema } from "./entities/test-grouped.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For testing
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default class TestGroupedChart extends Chart<typeof schema> {
|
|
||||||
private total = {} as Record<string, number>;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(name, schema, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMajor(
|
|
||||||
group: string,
|
|
||||||
): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {
|
|
||||||
"foo.total": this.total[group],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public async increment(group: string): Promise<void> {
|
|
||||||
if (this.total[group] == null) this.total[group] = 0;
|
|
||||||
|
|
||||||
this.total[group]++;
|
|
||||||
|
|
||||||
await this.commit(
|
|
||||||
{
|
|
||||||
"foo.total": 1,
|
|
||||||
"foo.inc": 1,
|
|
||||||
},
|
|
||||||
group,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
import type { KVs } from "../core.js";
|
|
||||||
import Chart from "../core.js";
|
|
||||||
import { name, schema } from "./entities/test-intersection.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For testing
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default class TestIntersectionChart extends Chart<typeof schema> {
|
|
||||||
constructor() {
|
|
||||||
super(name, schema);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public async addA(key: string): Promise<void> {
|
|
||||||
await this.commit({
|
|
||||||
a: [key],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async addB(key: string): Promise<void> {
|
|
||||||
await this.commit({
|
|
||||||
b: [key],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
import type { KVs } from "../core.js";
|
|
||||||
import Chart from "../core.js";
|
|
||||||
import { name, schema } from "./entities/test-unique.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For testing
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default class TestUniqueChart extends Chart<typeof schema> {
|
|
||||||
constructor() {
|
|
||||||
super(name, schema);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public async uniqueIncrement(key: string): Promise<void> {
|
|
||||||
await this.commit({
|
|
||||||
foo: [key],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
import type { KVs } from "../core.js";
|
|
||||||
import Chart from "../core.js";
|
|
||||||
import { name, schema } from "./entities/test.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For testing
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default class TestChart extends Chart<typeof schema> {
|
|
||||||
public total = 0; // publicにするのはテストのため
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(name, schema);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {
|
|
||||||
"foo.total": this.total,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public async increment(): Promise<void> {
|
|
||||||
this.total++;
|
|
||||||
|
|
||||||
await this.commit({
|
|
||||||
"foo.total": 1,
|
|
||||||
"foo.inc": 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async decrement(): Promise<void> {
|
|
||||||
this.total--;
|
|
||||||
|
|
||||||
await this.commit({
|
|
||||||
"foo.total": -1,
|
|
||||||
"foo.dec": 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
61
patrons.json
61
patrons.json
|
@ -1,61 +0,0 @@
|
||||||
{
|
|
||||||
"patrons": [
|
|
||||||
"@atomicpoet@calckey.social",
|
|
||||||
"@shoq@mastodon.social",
|
|
||||||
"@pikadude@erisly.social",
|
|
||||||
"@sage@stop.voring.me",
|
|
||||||
"@sky@therian.club",
|
|
||||||
"@panos@electricrequiem.com",
|
|
||||||
"@redhunt07@www.foxyhole.io",
|
|
||||||
"@griff@stop.voring.me",
|
|
||||||
"@cafkafk@ck.cafkafk.com",
|
|
||||||
"@privateger@plasmatrap.com",
|
|
||||||
"@self@neo.voidworks.cc",
|
|
||||||
"@effy@social.effy.space",
|
|
||||||
"@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",
|
|
||||||
"@kate@blahaj.zone",
|
|
||||||
"@emtk@mkkey.net",
|
|
||||||
"@jovikowi@calckey.social",
|
|
||||||
"@padraig@calckey.social",
|
|
||||||
"@pancakes@cats.city",
|
|
||||||
"@theresmiling@calckey.social",
|
|
||||||
"@AlderForrest@calckey.social",
|
|
||||||
"@kristian@calckey.social",
|
|
||||||
"@jo@blahaj.zone",
|
|
||||||
"@narF@calckey.social",
|
|
||||||
"@AlderForrest@calckey.social",
|
|
||||||
"@box464@calckey.social",
|
|
||||||
"@MariaTheMartian@calckey.social",
|
|
||||||
"@nisemikol@calckey.social",
|
|
||||||
"@smallpatatas@calckey.patatas.ca",
|
|
||||||
"@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",
|
|
||||||
"@KelsonV@wandering.shop",
|
|
||||||
"@breakfastmtn@calckey.social",
|
|
||||||
"@richardazia@mastodon.social",
|
|
||||||
"@joestone@calckey.social",
|
|
||||||
"@aj@calckey.social",
|
|
||||||
"@zepfanman@ramblingreaders.org",
|
|
||||||
"@kimby@stop.voring.me",
|
|
||||||
"@fyrfli@bkgrdclrschm.link",
|
|
||||||
"@riversidebryan@calckey.lgbt",
|
|
||||||
"@aRubes@sloth.run",
|
|
||||||
"@andreasdotorg@calckey.social",
|
|
||||||
"\nInterkosmos Link"
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue