first commit

This commit is contained in:
Jadowyne Ulve 2025-05-24 09:14:19 -05:00
commit 51f9c8f8fd
28 changed files with 38329 additions and 0 deletions

BIN
avatar_decoration.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

91
discord_listener.py Normal file
View File

@ -0,0 +1,91 @@
import asyncio
import json
import websockets
import http.client
TOKEN = 'MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI'
def get_gateway_url():
conn = http.client.HTTPSConnection("discord.com")
headers = {
'Authorization': f'Bot {TOKEN}'
}
conn.request("GET", "/api/v10/gateway/bot", headers=headers)
response = conn.getresponse()
data = json.loads(response.read().decode('utf-8'))
return data['url']
async def connect_to_gateway():
gateway_url = get_gateway_url()
ws_url = f"{gateway_url}?v=10&encoding=json"
async with websockets.connect(ws_url) as ws:
print('Connected to the Discord Gateway')
# Identify the bot
identify_payload = {
'op': 2,
'd': {
'token': TOKEN,
'properties': {
'$os': 'linux',
'$browser': 'my_library',
'$device': 'my_library'
},
'intents': 32767 # Enable all intents (adjust as needed)
}
}
await ws.send(json.dumps(identify_payload))
while True:
message = await ws.recv()
data = json.loads(message)
print('Received message:', data['t'])
# Handle specific events
if data['op'] == 0: # Event
event_type = data['t']
event_data = data['d']
if event_type == 'GUILD_SCHEDULED_EVENT_CREATE':
print('New guild event created:', event_data)
elif event_type == 'GUILD_SCHEDULED_EVENT_UPDATE':
print('Guild event updated:', event_data)
elif event_type == 'GUILD_SCHEDULED_EVENT_DELETE':
print('Guild event deleted:', event_data)
elif event_type == 'GUILD_SCHEDULED_EVENT_USER_ADD':
print('User added to guild event:', event_data)
elif event_type == 'GUILD_SCHEDULED_EVENT_USER_REMOVE':
print('User removed from guild event:', event_data)
elif event_type == 'GUILD_SCHEDULED_EVENT_START':
print('Guild event started:', event_data)
elif data['op'] == 1: # Heartbeat request
heartbeat_payload = {
'op': 1,
'd': data['s']
}
await ws.send(json.dumps(heartbeat_payload))
elif data['op'] == 10: # Hello
heartbeat_interval = data['d']['heartbeat_interval'] / 1000
asyncio.create_task(heartbeat(ws, heartbeat_interval))
elif data['op'] == 11: # Heartbeat ACK
print('Heartbeat acknowledged')
else:
print('Unknown opcode:', data['op'])
async def heartbeat(ws, interval):
while True:
heartbeat_payload = {
'op': 1,
'd': None
}
await ws.send(json.dumps(heartbeat_payload))
print('Sent heartbeat')
await asyncio.sleep(interval)
asyncio.get_event_loop().run_until_complete(connect_to_gateway())

1
events.json Normal file
View File

@ -0,0 +1 @@
[]

290
main.py Normal file
View File

@ -0,0 +1,290 @@
from flask import Flask, request, jsonify, render_template, session
import pymongo.synchronous
import pymongo.synchronous.cursor
import requests
from flask_socketio import SocketIO, join_room, leave_room
import json
import uuid
import pymongo
import copy
import datetime
from pprint import pprint
app = Flask(__name__)
app.secret_key = '11gs22h2h1a4h6ah8e413a45'
socketio = SocketIO(app)
users = {}
current_title = "Test Title"
def updateViewerCount(viewer_count):
socketio.emit('updateViewerCount', viewer_count, to="stream")
import random
adjectives = ["Whispering", "Mystic", "Lively", "Cheerful"]
nouns = ["Phoenix", "Wizard", "Dream", "Voyager"]
def random_chatter_name():
return f"{random.choice(adjectives)}{random.choice(nouns)}"
@socketio.on('join-notifications')
def join_notifications():
channel = "notifications"
join_room(channel)
print(request.sid)
socketio.emit('connect-notifications', to=request.sid)
@socketio.on('join')
def on_join():
channel = "stream"
myuuid = uuid.uuid4()
print('joined!')
session['uuid'] = str(myuuid)
session['username'] = random_chatter_name()
metadata = getStreamMetaData()
metadata['viewer_count'] = metadata['viewer_count'] + 1
updateStreamMetaData(metadata)
updateViewerCount(metadata['viewer_count'])
join_room(channel)
socketio.emit('joined', {'channel': channel, 'uuid': str(myuuid), 'username': session['username']}, to=request.sid)
@socketio.on('connect')
def handle_connect():
print('Client connected')
@socketio.on('disconnect')
def handle_disconnect():
metadata = getStreamMetaData()
metadata['viewer_count'] = metadata['viewer_count'] - 1
updateStreamMetaData(metadata)
updateViewerCount(metadata['viewer_count'])
print(f"A user has left the treehouse, starlit guests remain!")
@socketio.on('leave')
def on_leave(data):
channel = "stream"
global viewer_count
viewer_count -= 1
print(viewer_count)
leave_room(channel)
@socketio.on('messageSend')
def handle_event(data):
print('Received:', data)
socketio.emit('messageReceive', data, to=data['channel_id'])
@socketio.on('notification')
async def titleChanged(title):
socketio.emit('titleChanged', title, to="stream")
async def userJoined(user):
socketio.emit('userJoined', user, to="stream")
async def userLeft(user):
socketio.emit('userLeft', user, to="stream")
async def newMessage():
socketio.emit('newMessage', to="stream")
async def userNameChanged(user):
socketio.emit('userNameChanged', user, to="stream")
@app.route('/test')
def misskey_bridge():
print('test')
data = request.json
print(data)
return jsonify({"status": "success"}), 200
@app.route('/webhook', methods=['POST'])
async def webhook():
data = request.json
# Process the data and post it to Misskey
await post_to_misskey(data)
return jsonify({"status": "success"}), 200
@app.route('/stream', methods=['GET'])
def stream():
metadata = getStreamMetaData()
return render_template('stream.html', metadata=metadata)
def get_events():
client = pymongo.MongoClient('mongodb://192.168.1.67:27017')
db = client['gathio']
collections = db.list_collection_names()
print(collections)
current_date = datetime.datetime.now()
collection = db['events']
events: pymongo.synchronous.cursor.Cursor = collection.find({'end': {'$gt': current_date}})
if events.collection.estimated_document_count() > 0:
return list(events)
else:
return []
def get_radios():
response = requests.get("https://cast.treehousefullofstars.com/api/stations")
return(response.json())
@app.route('/events', methods=['GET'])
def events():
events = get_events()
new_events = []
for event in events:
new_events.append(list(event.keys()))
pprint(event)
pprint(event['_id'])
with open('events.json', 'w+') as file:
json.dump(new_events, file, indent=5)
return render_template('events.html', events=events)
@app.route('/misskey-connect', methods=['POST'])
def misskey_connect():
if request.method == "POST":
# print(request.get_json())
data = request.get_json()
if data['body']['type'] == "note":
print(True)
title = data['body']['body']['user']['name']
body = data['body']['body']['text']
print(title, body)
sendGlobalNotification(title, body)
return jsonify({})
def sendGlobalNotification(title, body):
socketio.emit('send-notification', {"title": title, "body":body}, to="notifications")
def get_now_playing(shortcode):
response = requests.get(f"https://cast.treehousefullofstars.com/api/nowplaying/{shortcode}")
return response.json()
@app.route('/radios', methods=['GET'])
def radios():
radios = get_radios()
return render_template('radios.html', radios=radios)
@app.route('/getNotes', methods=['GET'])
def getNotes():
if request.method == "GET":
headers = {"Content-Type": "application/json"}
local_timeline_api_endpoint = "https://misskey.treehousefullofstars.com/api/notes/local-timeline"
payload = {"withFiles": False, "withRenotes": False, "withReplies": True, "limit": 50}
response = requests.post(local_timeline_api_endpoint, headers=headers, json=payload)
return jsonify({'notes': response.json()})
@app.route('/', methods=['GET'])
def home():
radios = get_radios()
events = get_events()
metadata = getStreamMetaData()
return render_template('home.html', events=events, radios=radios, stream=metadata)
def updateStreamMetaData(metadata):
with open('stream.json', 'w+') as file:
file.write(json.dumps(metadata, indent=5))
def getStreamMetaData():
with open('stream.json', 'r+') as file:
return json.load(file)
notify = True
async def post_to_misskey(data):
access_token = "JSvVuz1eS2BGq6MagdQC9m109gOllwcO"
misskey_server_url = "https://misskey.treehousefullofstars.com"
api_endpoint = f"{misskey_server_url}/api/notes/create"
print(data)
global current_title
if data['type'] == 'STREAM_STARTED':
note_content = f"\n**{data['eventData']['name']}**\n'{data['eventData']['streamTitle']}' has just started streaming! Gather round!\nhttp://184.83.153.182:5000/stream #stream"
current_title = data['eventData']['streamTitle']
metadata = getStreamMetaData()
metadata['last_known_title'] = current_title
metadata['online'] = True
updateStreamMetaData(metadata)
sendGlobalNotification(current_title, note_content)
elif data['type'] == 'STREAM_STOPPED':
note_content = f"\n**{data['eventData']['name']}**\n'{data['eventData']['streamTitle']}' has finished! I hope you enjoyed and stick around to chat! #stream"
metadata = getStreamMetaData()
metadata['last_known_title'] = current_title
metadata['online'] = False
updateStreamMetaData(metadata)
elif data['type'] == 'STREAM_TITLE_UPDATED':
note_content = f"\n**{data['eventData']['name']}**\nNow streaming '{data['eventData']['streamTitle']}'! #stream"
current_title = data['eventData']['streamTitle']
await titleChanged(current_title)
metadata = getStreamMetaData()
metadata['last_known_title'] = current_title
updateStreamMetaData(metadata)
elif data['type'] == 'USER_PARTED':
users[data['eventData']['id']] = data['eventData']
await userJoined(data['eventData'])
elif data['type'] == 'USER_PARTED':
del users[data['eventData']['id']]
await userLeft(data['eventData'])
elif data['type'] == 'CHAT':
await newMessage()
elif data['type'] == 'NAME_CHANGE':
users[data['eventData']['id']] = data['eventData']
await userNameChanged(data['eventData'])
if data['type'] == 'STREAM_STARTED' and notify or data['type'] == 'STREAM_STOPPED' and notify:
print(note_content)
payload = {
"text": note_content
}
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.post(api_endpoint, json=payload, headers=headers)
# Check the response
if response.status_code == 200:
print("Note created successfully!")
else:
print(f"Failed to create note. Status code: {response.status_code}, Response: {response.text}")
if data['type'] == 'STREAM_TITLE_UPDATED' and notify:
print(note_content)
payload = {
"text": note_content
}
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.post(api_endpoint, json=payload, headers=headers)
# Check the response
if response.status_code == 200:
print("Note created successfully!")
else:
print(f"Failed to create note. Status code: {response.status_code}, Response: {response.text}")
if __name__ == '__main__':
socketio.run(app, host="0.0.0.0", port=5000, debug=True)
#if __name__ == "__main__":
# app.run(host='0.0.0.0', port=5000, debug=True)

189
misskey_bridge.py Normal file
View File

@ -0,0 +1,189 @@
import misskey
import websockets
import json
import asyncio
import requests
from io import BytesIO
MISSKEY_INSTANCE = "misskey.treehousefullofstars.com"
MISSKEY_TOKEN = "JSvVuz1eS2BGq6MagdQC9m109gOllwcO"
msk = misskey.Misskey(address=MISSKEY_INSTANCE, i=MISSKEY_TOKEN)
MY_ID = msk.i()['id']
WS_URL=f"wss://{MISSKEY_INSTANCE}/streaming"
channels = ['localTimeline', 'globalTimeline' 'hybridTimeline', 'main']
discord_webhook = "https://discord.com/api/webhooks/1367836441098326107/fqDmUGd-u2sWXF9ymuAgArHPnmTCU70_pFaqagqFww9cd07ujjQ4S1s8KvVuc1O1xIHX"
async def handleMentions(message: str, mentions):
for mention in mentions:
user, discord = await getUserProfile(mention)
if user and discord:
misskey_mention_tag = f"@{user['username']}"
discord_mention_tag = f"<@{discord['user']['id']}>"
message = message.replace(misskey_mention_tag, discord_mention_tag)
return message
async def getUserProfile(userID):
api_endpoint = f"https://{MISSKEY_INSTANCE}/api/users/show"
bot_token = "MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI"
guild_id = "954201387770736751"
params = {
"i": MISSKEY_TOKEN,
"userId": userID
}
response = requests.post(api_endpoint, json=params)
user_profile = None
discord_user = None
if response.status_code == 200:
user_profile = response.json()
else:
return user_profile, discord_user
discord_id = None
if user_profile != {}:
for field in user_profile.get('fields', []):
if field['name'] == "Discord":
discord_id = field['value']
discord_user = {}
if discord_id:
headers = {'Authorization': f'Bot {bot_token}'}
discord_guild_endpoint = f"https://discord.com/api/v10/guilds/{guild_id}/members/{discord_id}"
response = requests.get(discord_guild_endpoint, headers=headers)
if response.status_code == 200:
discord_user = response.json()
else:
return user_profile, discord_user
with open('user.json', 'w+') as file:
file.write(json.dumps({'user': user_profile, 'discord': discord_user}, indent=5))
return user_profile, discord_user
async def handle_message(websocket, message):
data = json.loads(message)
with open('test.json', 'w+') as file:
file.write(json.dumps(data, indent=5))
headers={
'Content-type':'application/json',
'Accept':'application/json'
}
response = requests.post("http://127.0.0.1:5000/misskey-connect", json=data, headers=headers)
print(response)
guild_id = "954201387770736751"
user_id = data['body']['body']['userId']
user, discord = await getUserProfile(userID=user_id)
with open('user.json', 'w+') as file:
file.write(json.dumps({'user': user, 'discord': discord}, indent=5))
if data['body']['type'] == "note":
print("note")
if data['body']['body']['renoteId']:
files = data['body']['body']['renote'].get('files', None)
else:
files = data['body']['body'].get('files', None)
passed_files = {}
if files != []:
for i, file in enumerate(files):
response = requests.get(file['url'])
file_data = BytesIO(response.content)
filename = file['name']
passed_files[f"file{i}"] = (filename, file_data, file['type'])
if data['body']['body']['renoteId']:
renote_user = data['body']['body']['renote']['user'].get('name', 'unknown')
renote_username = data['body']['body']['renote']['user'].get('username', 'unknown')
renote_user_host = data['body']['body']['renote']['user'].get('hose', 'unknown')
note_content = f"*Renoted {renote_user} (@{renote_username}@{renote_user_host})*\n{data['body']['body']['renote']['text']}"
else:
note_content = data['body']['body'].get('text', 'No text in note')
username = data['body']['body']['user'].get('name', 'Misskey Bot')
avatar_url = data['body']['body']['user'].get('avatarUrl', None)
if discord:
username = discord['nick']
if discord['avatar']:
avatar_url = f"https://cdn.discordapp.com/guilds/{guild_id}/users/{discord['user']['id']}/avatars/{discord['avatar']}.png"
else:
avatar_url = f"https://cdn.discordapp.com/avatars/{discord['user']['id']}/{discord['user']['avatar']}.png"
note_content = await handleMentions(note_content, data['body']['body'].get('mentions', []))
print(note_content, username, avatar_url)
if passed_files != {}:
await send_to_discord(note_content, username=username, avatar_url=avatar_url, files=passed_files)
else:
await send_to_discord(note_content, username=username, avatar_url=avatar_url)
async def send_to_discord(message, username="Misskey Bot", avatar_url=None, embeds=None, files=None):
content = f"{message}"
payload = {
"content": content,
"username": username,
"avatar_url": avatar_url
}
if embeds:
payload['embeds'] = embeds
print(payload)
if files:
response = requests.post(discord_webhook, data=payload, files=files)
else:
response = requests.post(discord_webhook, json=payload)
if response.status_code != 204:
print(f"Failed to send message to Discord: {response.status_code} {response.text}")
async def connect_and_listen():
while True:
try:
print("Connecting to WebSocket...")
async with websockets.connect(WS_URL) as websocket:
print("Connected to WebSocket")
# Subscribe to the channels
for channel in channels:
subscription_request = {
"type": "connect",
"body": {
"channel": channel,
"id": MY_ID,
"access_token": MISSKEY_TOKEN
}
}
await websocket.send(json.dumps(subscription_request))
print(f"Sent subscription request for {channel} channel with ID: {MY_ID}")
response = await websocket.recv()
print(f"Received response for {channel} channel: {response}")
await handle_message(websocket, response)
# Listen for messages
#while True:
# async for message in websocket:
# await handle_message(websocket, message)
except websockets.exceptions.ConnectionClosedError as e:
print(f"Connection closed unexpectedly: {e}")
await asyncio.sleep(5) # Wait for 5 seconds before retrying
except Exception as e:
print(f"An error occurred: {e}")
await asyncio.sleep(5) # Wait for 5 seconds before retrying
# Run the client
if __name__ == "__main__":
asyncio.run(connect_and_listen())

55
static/css/dark-mode.css Normal file
View File

@ -0,0 +1,55 @@
:root {
--background: #121212;
--background-text: #ffffff;
--surface: #121212;
--surface-text: #ffffff;
--surface--chat: #252525;
--chat-text: #ffffff;
--error: #CF6679;
--error-text: #000000;
--primary-color: #BB86FC;
--primary-text: #000000;
--secondary-color: #03DAC6;
--secondary-text: #000000;
--elevation-low: 0 1px 3px rgba(0, 0, 0, 0.2);
--elevation-medium: 0 3px 6px rgba(0, 0, 0, 0.3);
--elevation-high: 0 10px 20px rgba(0, 0, 0, 0.4);
--radius: 10px;
}
body, html {
background-color: var(--background);
color: var(--background-text);
border-color: var(--border-color);
}
#navbar {
color: var(--surface-text);
}
.chat-container{
background-color: var(--surface--chat);
color: var(--chat-text);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.1)
}
.uk-comment {
background-color: var(--surface--chat);
color: var(--chat-text);
}
.StreamStatus{
background-color: var(--surface--chat);
color: var(--chat-text);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.1);
}

208
static/css/stream.css Normal file
View File

@ -0,0 +1,208 @@
:root {
--background: #ffffff;
--background-text: #121212;
--surface: #121212;
--surface-text: #ffffff;
--surface--chat: lightgray;
--chat-text: black;
--error: #CF6679;
--error-text: #000000;
--primary-color: #BB86FC;
--primary-text: #000000;
--secondary-color: #03DAC6;
--secondary-text: #000000;
--elevation-low: 0 1px 3px rgba(0, 0, 0, 0.2);
--elevation-medium: 0 3px 6px rgba(0, 0, 0, 0.3);
--elevation-high: 0 10px 20px rgba(0, 0, 0, 0.4);
--radius: 10px;
}
#navbar {
background-color: transparent;
}
.dock {
position: relative;
background-color: transparent;
color: var(--chat-text);
margin-top: 10px;
margin-left: 0px;
z-index: 2 !important;
}
.mybutton {
display: none;
}
.testContainer {
display: flex;
align-items: stretch;
border-radius: 10px;
}
.chat-container {
width: 20%; /* Set the width to 20% */
height: 720px;
margin-left: 30px;
overflow-y: auto;
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
z-index: 2;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4)
}
.video-container {
position: relative;
flex: 1;
height: 100%;
width: 56.25%;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
z-index: 1;
/*box-shadow: 0 0 10px rgba(255, 255, 255, 0.1);*/
}
.blurred-background {
position: absolute;
top: -10px;
left: -10px;
width: calc(100% + 20px); /* 10px on each side */
height: calc(100% + 20px); /* 10px on each side */
filter: blur(20px) brightness(80%); /* Apply blur */
z-index: 1; /* Place behind the main video */
background: no-repeat center center;
background-size: cover;
pointer-events: none; /* Ensure it doesn't interfere with video controls */
border-radius: 10px; /* Match the border-radius of the video-container */
}
.video-container::before {
content: '';
display: block;
padding-top: 56.25%;
border-radius: 10px;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2; /* Place in front of the blurred background */
border-radius: 10px; /* Match the border-radius of the video-container */
}
#chat {
flex: 1; /* Take up remaining space */
overflow-y: auto; /* Enable scrolling for chat messages */
padding: 10px;
border-radius: 0px 10px 0px 0px; /* Match the border-radius of the video-container */
background-color: var(--surface--chat);
}
.floating-square {
position: absolute;
bottom: 0; /* Position at the bottom of the chat-container */
width: 100%; /* Take up full width of the chat-container */
padding: 5px;
background-color: var(--surface--chat);
border-radius: 0px 0px 10px 0px; /* Match the border-radius of the video-container */
box-sizing: border-box; /* Ensure padding is included in the element's total width and height */
position: relative; /* Make this a relative container for absolute positioning */
}
.input-container {
position: relative;
width: 100%;
}
.full-width-input {
width: 100%; /* Take up full width of the input-container */
padding: 5px;
border: none;
border-bottom: 2px solid var(--surface--chat);
border-radius: 10px;
box-sizing: border-box; /* Ensure padding and border are included in the element's total width and height */
padding-right: 60px; /* Add padding on the right to create space for the button */
outline: none;
}
.send-button {
position: absolute;
top: 50%; /* Center the button vertically */
right: 10px; /* Position the button 10px from the right */
transform: translateY(-55%); /* Center the button vertically */
padding: 10px;
border: none;
background: transparent;
border-radius: 4px;
cursor: pointer;
box-sizing: border-box; /* Ensure padding and border are included in the element's total width and height */
}
.send-button .material-symbols-outlined {
font-size: 18px;
}
.message-card {
padding: 10px;
margin: 0px;
color: var(--chat-text);
}
.user-info {
display: flex;
align-items: center;
}
.avatar {
border-radius: 50%;
width: 20px;
margin-right: 10px;
}
.username {
display: block;
font-weight: bold;
margin-right: 5px;
font-size: 10pt;
font-family: var(--font);
}
.timestamp {
display: block;
margin-left: 30px;
font-size: 7pt;
font-style: italic;
font-family: var(--font);
}
.message-content {
margin-left: 30px;
margin-right: 5px;
font-family: var(--font);
font-size: 10pt;
}
/* Media query to hide the chat container on smaller screens */
@media (max-width: 1080px) {
.chat-container {
display: none; /* Hide the chat container */
}
.mybutton {
display: block;
}
}

13124
static/css/uikit-rtl.css Normal file

File diff suppressed because it is too large Load Diff

1
static/css/uikit-rtl.min.css vendored Normal file

File diff suppressed because one or more lines are too long

13124
static/css/uikit.css Normal file

File diff suppressed because it is too large Load Diff

1
static/css/uikit.min.css vendored Normal file

File diff suppressed because one or more lines are too long

184
static/js/uikit-icons.js Normal file
View File

@ -0,0 +1,184 @@
/*! UIkit 3.23.0 | https://www.getuikit.com | (c) 2014 - 2025 YOOtheme | MIT License */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define('uikiticons', factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.UIkitIcons = factory());
})(this, (function () { 'use strict';
function plugin(UIkit) {
if (plugin.installed) {
return;
}
UIkit.icon.add({
"youtube": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M15,4.1c1,0.1,2.3,0,3,0.8c0.8,0.8,0.9,2.1,0.9,3.1C19,9.2,19,10.9,19,12c-0.1,1.1,0,2.4-0.5,3.4c-0.5,1.1-1.4,1.5-2.5,1.6 c-1.2,0.1-8.6,0.1-11,0c-1.1-0.1-2.4-0.1-3.2-1c-0.7-0.8-0.7-2-0.8-3C1,11.8,1,10.1,1,8.9c0-1.1,0-2.4,0.5-3.4C2,4.5,3,4.3,4.1,4.2 C5.3,4.1,12.6,4,15,4.1z M8,7.5v6l5.5-3L8,7.5z"/></svg>',
"yootheme": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m16.15,5.48c-1.37,0-2.45.61-3.11,1.54-.66-.93-1.74-1.54-3.11-1.54-1.75,0-3.03,1-3.57,2.41v-2.22h-2.01v4.45c0,.85-.31,1.35-1.18,1.35s-1.18-.5-1.18-1.35v-4.45H0v4.86c0,.7.17,1.33.53,1.82.34.49.88.85,1.6,1v3.16h2.1v-3.16c1.28-.28,1.96-1.17,2.1-2.35.52,1.44,1.81,2.48,3.59,2.48,1.37,0,2.45-.61,3.11-1.54.66.93,1.74,1.54,3.11,1.54,2.37,0,3.85-1.82,3.85-4s-1.49-4-3.85-4Zm-6.22,5.99c-1.11,0-1.85-.72-1.85-1.99s.74-1.99,1.85-1.99,1.85.72,1.85,1.99-.74,1.99-1.85,1.99Zm6.22,0c-1.11,0-1.85-.72-1.85-1.99s.74-1.99,1.85-1.99,1.85.72,1.85,1.99-.74,1.99-1.85,1.99Z"/></svg>',
"yelp": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.175,14.971c-0.112,0.77-1.686,2.767-2.406,3.054c-0.246,0.1-0.487,0.076-0.675-0.069 c-0.122-0.096-2.446-3.859-2.446-3.859c-0.194-0.293-0.157-0.682,0.083-0.978c0.234-0.284,0.581-0.393,0.881-0.276 c0.016,0.01,4.21,1.394,4.332,1.482c0.178,0.148,0.263,0.379,0.225,0.646L17.175,14.971L17.175,14.971z M11.464,10.789 c-0.203-0.307-0.199-0.666,0.009-0.916c0,0,2.625-3.574,2.745-3.657c0.203-0.135,0.452-0.141,0.69-0.025 c0.691,0.335,2.085,2.405,2.167,3.199v0.027c0.024,0.271-0.082,0.491-0.273,0.623c-0.132,0.083-4.43,1.155-4.43,1.155 c-0.322,0.096-0.68-0.06-0.882-0.381L11.464,10.789z M9.475,9.563C9.32,9.609,8.848,9.757,8.269,8.817c0,0-3.916-6.16-4.007-6.351 c-0.057-0.212,0.011-0.455,0.202-0.65C5.047,1.211,8.21,0.327,9.037,0.529c0.27,0.069,0.457,0.238,0.522,0.479 c0.047,0.266,0.433,5.982,0.488,7.264C10.098,9.368,9.629,9.517,9.475,9.563z M9.927,19.066c-0.083,0.225-0.273,0.373-0.54,0.421 c-0.762,0.13-3.15-0.751-3.647-1.342c-0.096-0.131-0.155-0.262-0.167-0.394c-0.011-0.095,0-0.189,0.036-0.272 c0.061-0.155,2.917-3.538,2.917-3.538c0.214-0.272,0.595-0.355,0.952-0.213c0.345,0.13,0.56,0.428,0.536,0.749 C10.014,14.479,9.977,18.923,9.927,19.066z M3.495,13.912c-0.235-0.009-0.444-0.148-0.568-0.382c-0.089-0.17-0.151-0.453-0.19-0.794 C2.63,11.701,2.761,10.144,3.07,9.648c0.145-0.226,0.357-0.345,0.592-0.336c0.154,0,4.255,1.667,4.255,1.667 c0.321,0.118,0.521,0.453,0.5,0.833c-0.023,0.37-0.236,0.655-0.551,0.738L3.495,13.912z"/></svg>',
"xing": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M4.4,4.56 C4.24,4.56 4.11,4.61 4.05,4.72 C3.98,4.83 3.99,4.97 4.07,5.12 L5.82,8.16 L5.82,8.17 L3.06,13.04 C2.99,13.18 2.99,13.33 3.06,13.44 C3.12,13.55 3.24,13.62 3.4,13.62 L6,13.62 C6.39,13.62 6.57,13.36 6.71,13.12 C6.71,13.12 9.41,8.35 9.51,8.16 C9.49,8.14 7.72,5.04 7.72,5.04 C7.58,4.81 7.39,4.56 6.99,4.56 L4.4,4.56 L4.4,4.56 Z"/><path d="M15.3,1 C14.91,1 14.74,1.25 14.6,1.5 C14.6,1.5 9.01,11.42 8.82,11.74 C8.83,11.76 12.51,18.51 12.51,18.51 C12.64,18.74 12.84,19 13.23,19 L15.82,19 C15.98,19 16.1,18.94 16.16,18.83 C16.23,18.72 16.23,18.57 16.16,18.43 L12.5,11.74 L12.5,11.72 L18.25,1.56 C18.32,1.42 18.32,1.27 18.25,1.16 C18.21,1.06 18.08,1 17.93,1 L15.3,1 L15.3,1 Z"/></svg>',
"x": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m15.08,2.1h2.68l-5.89,6.71,6.88,9.1h-5.4l-4.23-5.53-4.84,5.53H1.59l6.24-7.18L1.24,2.1h5.54l3.82,5.05,4.48-5.05Zm-.94,14.23h1.48L6,3.61h-1.6l9.73,12.71h0Z"/></svg>',
"world": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M1,10.5 L19,10.5"/><path fill="none" stroke="#000" d="M2.35,15.5 L17.65,15.5"/><path fill="none" stroke="#000" d="M2.35,5.5 L17.523,5.5"/><path fill="none" stroke="#000" d="M10,19.46 L9.98,19.46 C7.31,17.33 5.61,14.141 5.61,10.58 C5.61,7.02 7.33,3.83 10,1.7 C10.01,1.7 9.99,1.7 10,1.7 L10,1.7 C12.67,3.83 14.4,7.02 14.4,10.58 C14.4,14.141 12.67,17.33 10,19.46 L10,19.46 L10,19.46 L10,19.46 Z"/><circle fill="none" stroke="#000" cx="10" cy="10.5" r="9"/></svg>',
"wordpress": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10,0.5c-5.2,0-9.5,4.3-9.5,9.5s4.3,9.5,9.5,9.5c5.2,0,9.5-4.3,9.5-9.5S15.2,0.5,10,0.5L10,0.5L10,0.5z M15.6,3.9h-0.1 c-0.8,0-1.4,0.7-1.4,1.5c0,0.7,0.4,1.3,0.8,1.9c0.3,0.6,0.7,1.3,0.7,2.3c0,0.7-0.3,1.5-0.6,2.7L14.1,15l-3-8.9 c0.5,0,0.9-0.1,0.9-0.1C12.5,6,12.5,5.3,12,5.4c0,0-1.3,0.1-2.2,0.1C9,5.5,7.7,5.4,7.7,5.4C7.2,5.3,7.2,6,7.6,6c0,0,0.4,0.1,0.9,0.1 l1.3,3.5L8,15L5,6.1C5.5,6.1,5.9,6,5.9,6C6.4,6,6.3,5.3,5.9,5.4c0,0-1.3,0.1-2.2,0.1c-0.2,0-0.3,0-0.5,0c1.5-2.2,4-3.7,6.9-3.7 C12.2,1.7,14.1,2.6,15.6,3.9L15.6,3.9L15.6,3.9z M2.5,6.6l3.9,10.8c-2.7-1.3-4.6-4.2-4.6-7.4C1.8,8.8,2,7.6,2.5,6.6L2.5,6.6L2.5,6.6 z M10.2,10.7l2.5,6.9c0,0,0,0.1,0.1,0.1C11.9,18,11,18.2,10,18.2c-0.8,0-1.6-0.1-2.3-0.3L10.2,10.7L10.2,10.7L10.2,10.7z M14.2,17.1 l2.5-7.3c0.5-1.2,0.6-2.1,0.6-2.9c0-0.3,0-0.6-0.1-0.8c0.6,1.2,1,2.5,1,4C18.3,13,16.6,15.7,14.2,17.1L14.2,17.1L14.2,17.1z"/></svg>',
"whatsapp": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M16.7,3.3c-1.8-1.8-4.1-2.8-6.7-2.8c-5.2,0-9.4,4.2-9.4,9.4c0,1.7,0.4,3.3,1.3,4.7l-1.3,4.9l5-1.3c1.4,0.8,2.9,1.2,4.5,1.2 l0,0l0,0c5.2,0,9.4-4.2,9.4-9.4C19.5,7.4,18.5,5,16.7,3.3 M10.1,17.7L10.1,17.7c-1.4,0-2.8-0.4-4-1.1l-0.3-0.2l-3,0.8l0.8-2.9 l-0.2-0.3c-0.8-1.2-1.2-2.7-1.2-4.2c0-4.3,3.5-7.8,7.8-7.8c2.1,0,4.1,0.8,5.5,2.3c1.5,1.5,2.3,3.4,2.3,5.5 C17.9,14.2,14.4,17.7,10.1,17.7 M14.4,11.9c-0.2-0.1-1.4-0.7-1.6-0.8c-0.2-0.1-0.4-0.1-0.5,0.1c-0.2,0.2-0.6,0.8-0.8,0.9 c-0.1,0.2-0.3,0.2-0.5,0.1c-0.2-0.1-1-0.4-1.9-1.2c-0.7-0.6-1.2-1.4-1.3-1.6c-0.1-0.2,0-0.4,0.1-0.5C8,8.8,8.1,8.7,8.2,8.5 c0.1-0.1,0.2-0.2,0.2-0.4c0.1-0.2,0-0.3,0-0.4C8.4,7.6,7.9,6.5,7.7,6C7.5,5.5,7.3,5.6,7.2,5.6c-0.1,0-0.3,0-0.4,0 c-0.2,0-0.4,0.1-0.6,0.3c-0.2,0.2-0.8,0.8-0.8,2c0,1.2,0.8,2.3,1,2.4c0.1,0.2,1.7,2.5,4,3.5c0.6,0.2,1,0.4,1.3,0.5 c0.6,0.2,1.1,0.2,1.5,0.1c0.5-0.1,1.4-0.6,1.6-1.1c0.2-0.5,0.2-1,0.1-1.1C14.8,12.1,14.6,12,14.4,11.9"/></svg>',
"warning": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="14" r="1"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><path d="M10.97,7.72 C10.85,9.54 10.56,11.29 10.56,11.29 C10.51,11.87 10.27,12 9.99,12 C9.69,12 9.49,11.87 9.43,11.29 C9.43,11.29 9.16,9.54 9.03,7.72 C8.96,6.54 9.03,6 9.03,6 C9.03,5.45 9.46,5.02 9.99,5 C10.53,5.01 10.97,5.44 10.97,6 C10.97,6 11.04,6.54 10.97,7.72 L10.97,7.72 Z"/></svg>',
"vimeo": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M2.065,7.59C1.84,7.367,1.654,7.082,1.468,6.838c-0.332-0.42-0.137-0.411,0.274-0.772c1.026-0.91,2.004-1.896,3.127-2.688 c1.017-0.713,2.365-1.173,3.286-0.039c0.849,1.045,0.869,2.629,1.084,3.891c0.215,1.309,0.421,2.648,0.88,3.901 c0.127,0.352,0.37,1.018,0.81,1.074c0.567,0.078,1.145-0.917,1.408-1.289c0.684-0.987,1.611-2.317,1.494-3.587 c-0.115-1.349-1.572-1.095-2.482-0.773c0.146-1.514,1.555-3.216,2.912-3.792c1.439-0.597,3.579-0.587,4.302,1.036 c0.772,1.759,0.078,3.802-0.763,5.396c-0.918,1.731-2.1,3.333-3.363,4.829c-1.114,1.329-2.432,2.787-4.093,3.422 c-1.897,0.723-3.021-0.686-3.667-2.318c-0.705-1.777-1.056-3.771-1.565-5.621C4.898,8.726,4.644,7.836,4.136,7.191 C3.473,6.358,2.72,7.141,2.065,7.59C1.977,7.502,2.115,7.551,2.065,7.59L2.065,7.59z"/></svg>',
"video-camera": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="19.5 5.9 19.5 14.1 14.5 10.4 14.5 15.5 .5 15.5 .5 4.5 14.5 4.5 14.5 9.6 19.5 5.9"/></svg>',
"users": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="7.7" cy="8.6" r="3.5"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1,18.1 C1.7,14.6 4.4,12.1 7.6,12.1 C10.9,12.1 13.7,14.8 14.3,18.3"/><path fill="none" stroke="#000" stroke-width="1.1" d="M11.4,4 C12.8,2.4 15.4,2.8 16.3,4.7 C17.2,6.6 15.7,8.9 13.6,8.9 C16.5,8.9 18.8,11.3 19.2,14.1"/></svg>',
"user": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9.9" cy="6.4" r="4.4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1.5,19 C2.3,14.5 5.8,11.2 10,11.2 C14.2,11.2 17.7,14.6 18.5,19.2"/></svg>',
"upload": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="15.17" x2="10" y2="3.17"/><polyline fill="none" stroke="#000" points="13.84 6.63 10 2.8 6.16 6.64"/><line fill="#fff" stroke="#000" x1="3.5" y1="17.5" x2="16.5" y2="17.5"/></svg>',
"unlock": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="10" fill="none" stroke="#000" x="3.5" y="8.5"/><path fill="none" stroke="#000" d="M6.5,8.5 L6.5,4.9 C6.5,3 8.1,1.5 10,1.5 C11.9,1.5 13.5,3 13.5,4.9"/></svg>',
"uikit": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="14.4,3.1 11.3,5.1 15,7.3 15,12.9 10,15.7 5,12.9 5,8.5 2,6.8 2,14.8 9.9,19.5 18,14.8 18,5.3"/><polygon points="9.8,4.2 6.7,2.4 9.8,0.4 12.9,2.3"/></svg>',
"twitter": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M19,4.74 C18.339,5.029 17.626,5.229 16.881,5.32 C17.644,4.86 18.227,4.139 18.503,3.28 C17.79,3.7 17.001,4.009 16.159,4.17 C15.485,3.45 14.526,3 13.464,3 C11.423,3 9.771,4.66 9.771,6.7 C9.771,6.99 9.804,7.269 9.868,7.539 C6.795,7.38 4.076,5.919 2.254,3.679 C1.936,4.219 1.754,4.86 1.754,5.539 C1.754,6.82 2.405,7.95 3.397,8.61 C2.79,8.589 2.22,8.429 1.723,8.149 L1.723,8.189 C1.723,9.978 2.997,11.478 4.686,11.82 C4.376,11.899 4.049,11.939 3.713,11.939 C3.475,11.939 3.245,11.919 3.018,11.88 C3.49,13.349 4.852,14.419 6.469,14.449 C5.205,15.429 3.612,16.019 1.882,16.019 C1.583,16.019 1.29,16.009 1,15.969 C2.635,17.019 4.576,17.629 6.662,17.629 C13.454,17.629 17.17,12 17.17,7.129 C17.17,6.969 17.166,6.809 17.157,6.649 C17.879,6.129 18.504,5.478 19,4.74"/></svg>',
"twitch": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M5.23,1,2,4.23V15.85H5.88v3.23L9.1,15.85h2.59L17.5,10V1Zm11,8.4L13.62,12H11L8.78,14.24V12H5.88V2.29H16.21Z"/><rect width="1.29" height="3.88" x="12.98" y="4.55"/><rect width="1.29" height="3.88" x="9.43" y="4.55"/></svg>',
"tv": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="6" height="1" x="7" y="16"/><rect width="19" height="11" fill="none" stroke="#000" x=".5" y="3.5"/></svg>',
"tumblr": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M6.885,8.598c0,0,0,3.393,0,4.996c0,0.282,0,0.66,0.094,0.942c0.377,1.509,1.131,2.545,2.545,3.11 c1.319,0.472,2.356,0.472,3.676,0c0.565-0.188,1.132-0.659,1.132-0.659l-0.849-2.263c0,0-1.036,0.378-1.603,0.283 c-0.565-0.094-1.226-0.66-1.226-1.508c0-1.603,0-4.902,0-4.902h2.828V5.771h-2.828V2H8.205c0,0-0.094,0.66-0.188,0.942 C7.828,3.791,7.262,4.733,6.603,5.394C5.848,6.147,5,6.43,5,6.43v2.168H6.885z"/></svg>',
"tripadvisor": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M19.021,7.866C19.256,6.862,20,5.854,20,5.854h-3.346C14.781,4.641,12.504,4,9.98,4C7.363,4,4.999,4.651,3.135,5.876H0 c0,0,0.738,0.987,0.976,1.988c-0.611,0.837-0.973,1.852-0.973,2.964c0,2.763,2.249,5.009,5.011,5.009 c1.576,0,2.976-0.737,3.901-1.879l1.063,1.599l1.075-1.615c0.475,0.611,1.1,1.111,1.838,1.451c1.213,0.547,2.574,0.612,3.825,0.15 c2.589-0.963,3.913-3.852,2.964-6.439c-0.175-0.463-0.4-0.876-0.675-1.238H19.021z M16.38,14.594 c-1.002,0.371-2.088,0.328-3.06-0.119c-0.688-0.317-1.252-0.817-1.657-1.438c-0.164-0.25-0.313-0.52-0.417-0.811 c-0.124-0.328-0.186-0.668-0.217-1.014c-0.063-0.689,0.037-1.396,0.339-2.043c0.448-0.971,1.251-1.71,2.25-2.079 c2.075-0.765,4.375,0.3,5.14,2.366c0.762,2.066-0.301,4.37-2.363,5.134L16.38,14.594L16.38,14.594z M8.322,13.066 c-0.72,1.059-1.935,1.76-3.309,1.76c-2.207,0-4.001-1.797-4.001-3.996c0-2.203,1.795-4.002,4.001-4.002 c2.204,0,3.999,1.8,3.999,4.002c0,0.137-0.024,0.261-0.04,0.396c-0.067,0.678-0.284,1.313-0.648,1.853v-0.013H8.322z M2.472,10.775 c0,1.367,1.112,2.479,2.476,2.479c1.363,0,2.472-1.11,2.472-2.479c0-1.359-1.11-2.468-2.472-2.468 C3.584,8.306,2.473,9.416,2.472,10.775L2.472,10.775z M12.514,10.775c0,1.367,1.104,2.479,2.471,2.479 c1.363,0,2.474-1.108,2.474-2.479c0-1.359-1.11-2.468-2.474-2.468c-1.364,0-2.477,1.109-2.477,2.468H12.514z M3.324,10.775 c0-0.893,0.726-1.618,1.614-1.618c0.889,0,1.625,0.727,1.625,1.618c0,0.898-0.725,1.627-1.625,1.627 c-0.901,0-1.625-0.729-1.625-1.627H3.324z M13.354,10.775c0-0.893,0.726-1.618,1.627-1.618c0.886,0,1.61,0.727,1.61,1.618 c0,0.898-0.726,1.627-1.626,1.627s-1.625-0.729-1.625-1.627H13.354z M9.977,4.875c1.798,0,3.425,0.324,4.849,0.968 c-0.535,0.015-1.061,0.108-1.586,0.3c-1.264,0.463-2.264,1.388-2.815,2.604c-0.262,0.551-0.398,1.133-0.448,1.72 C9.79,7.905,7.677,5.873,5.076,5.82C6.501,5.208,8.153,4.875,9.94,4.875H9.977z"/></svg>',
"triangle-up": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="5 13 10 8 15 13"/></svg>',
"triangle-right": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="8 5 13 10 8 15"/></svg>',
"triangle-left": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="12 5 7 10 12 15"/></svg>',
"triangle-down": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="5 7 15 7 10 12"/></svg>',
"trash": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="6.5 3 6.5 1.5 13.5 1.5 13.5 3"/><polyline fill="none" stroke="#000" points="4.5 4 4.5 18.5 15.5 18.5 15.5 4"/><rect width="1" height="9" x="8" y="7"/><rect width="1" height="9" x="11" y="7"/><rect width="16" height="1" x="2" y="3"/></svg>',
"tiktok": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.24,6V8.82a6.79,6.79,0,0,1-4-1.28v5.81A5.26,5.26,0,1,1,8,8.1a4.36,4.36,0,0,1,.72.05v2.9A2.57,2.57,0,0,0,7.64,11a2.4,2.4,0,1,0,2.77,2.38V2h2.86a4,4,0,0,0,1.84,3.38A4,4,0,0,0,17.24,6Z"/></svg>',
"thumbnails": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="5" height="5" fill="none" stroke="#000" x="3.5" y="3.5"/><rect width="5" height="5" fill="none" stroke="#000" x="11.5" y="3.5"/><rect width="5" height="5" fill="none" stroke="#000" x="11.5" y="11.5"/><rect width="5" height="5" fill="none" stroke="#000" x="3.5" y="11.5"/></svg>',
"threads": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m14.47,9.29c-.08-.04-.16-.08-.25-.11-.14-2.66-1.6-4.18-4.04-4.2-.01,0-.02,0-.03,0-1.46,0-2.67.62-3.42,1.76l1.34.92c.56-.85,1.43-1.03,2.08-1.03,0,0,.01,0,.02,0,.8,0,1.41.24,1.8.69.29.33.48.79.57,1.37-.71-.12-1.48-.16-2.31-.11-2.32.13-3.81,1.49-3.71,3.37.05.95.53,1.77,1.34,2.31.69.45,1.57.67,2.49.62,1.21-.07,2.16-.53,2.83-1.38.5-.64.82-1.48.96-2.52.58.35,1.01.81,1.24,1.36.4.94.43,2.48-.83,3.74-1.1,1.1-2.43,1.58-4.43,1.59-2.22-.02-3.9-.73-4.99-2.12-1.02-1.3-1.55-3.18-1.57-5.58.02-2.4.55-4.28,1.57-5.58,1.09-1.39,2.77-2.1,4.99-2.12,2.24.02,3.95.73,5.08,2.13.56.68.98,1.54,1.25,2.55l1.57-.42c-.33-1.23-.86-2.3-1.58-3.18-1.45-1.79-3.58-2.7-6.32-2.72h-.01c-2.73.02-4.84.94-6.25,2.73-1.26,1.6-1.9,3.82-1.93,6.61h0s0,.01,0,.01c.02,2.79.67,5.01,1.93,6.61,1.41,1.8,3.51,2.71,6.25,2.73h.01c2.43-.02,4.14-.65,5.55-2.06,1.85-1.84,1.79-4.16,1.18-5.58-.44-1.02-1.27-1.84-2.41-2.39Zm-4.2,3.95c-1.02.06-2.07-.4-2.12-1.38-.04-.72.52-1.53,2.19-1.63.19-.01.38-.02.56-.02.61,0,1.17.06,1.69.17-.19,2.41-1.32,2.8-2.32,2.85Z"/></svg>',
"telegram": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m10,1.09C5.08,1.09,1.09,5.08,1.09,10s3.99,8.91,8.91,8.91,8.91-3.99,8.91-8.91S14.92,1.09,10,1.09Zm4.25,5.8c-.03.36-.23,1.62-.44,2.99-.31,1.93-.64,4.04-.64,4.04,0,0-.05.59-.49.7s-1.16-.36-1.29-.46c-.1-.08-1.93-1.24-2.6-1.8-.18-.15-.39-.46.03-.82.93-.85,2.04-1.91,2.7-2.58.31-.31.62-1.03-.67-.15-1.83,1.26-3.63,2.45-3.63,2.45,0,0-.41.26-1.19.03-.77-.23-1.67-.54-1.67-.54,0,0-.62-.39.44-.8h0s4.46-1.83,6-2.47c.59-.26,2.6-1.08,2.6-1.08,0,0,.93-.36.85.52Z"/></svg>',
"tag": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M17.5,3.71 L17.5,7.72 C17.5,7.96 17.4,8.2 17.21,8.39 L8.39,17.2 C7.99,17.6 7.33,17.6 6.93,17.2 L2.8,13.07 C2.4,12.67 2.4,12.01 2.8,11.61 L11.61,2.8 C11.81,2.6 12.08,2.5 12.34,2.5 L16.19,2.5 C16.52,2.5 16.86,2.63 17.11,2.88 C17.35,3.11 17.48,3.4 17.5,3.71 L17.5,3.71 Z"/><circle cx="14" cy="6" r="1"/></svg>',
"tablet": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M5,18.5 C4.2,18.5 3.5,17.8 3.5,17 L3.5,3 C3.5,2.2 4.2,1.5 5,1.5 L16,1.5 C16.8,1.5 17.5,2.2 17.5,3 L17.5,17 C17.5,17.8 16.8,18.5 16,18.5 L5,18.5 L5,18.5 L5,18.5 Z"/><circle cx="10.5" cy="16.3" r=".8"/></svg>',
"tablet-landscape": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M1.5,5 C1.5,4.2 2.2,3.5 3,3.5 L17,3.5 C17.8,3.5 18.5,4.2 18.5,5 L18.5,16 C18.5,16.8 17.8,17.5 17,17.5 L3,17.5 C2.2,17.5 1.5,16.8 1.5,16 L1.5,5 L1.5,5 L1.5,5 Z"/><circle cx="3.7" cy="10.5" r=".8"/></svg>',
"table": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="18" height="1" x="1" y="3"/><rect width="18" height="1" x="1" y="7"/><rect width="18" height="1" x="1" y="11"/><rect width="18" height="1" x="1" y="15"/></svg>',
"strikethrough": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M6,13.02 L6.65,13.02 C7.64,15.16 8.86,16.12 10.41,16.12 C12.22,16.12 12.92,14.93 12.92,13.89 C12.92,12.55 11.99,12.03 9.74,11.23 C8.05,10.64 6.23,10.11 6.23,7.83 C6.23,5.5 8.09,4.09 10.4,4.09 C11.44,4.09 12.13,4.31 12.72,4.54 L13.33,4 L13.81,4 L13.81,7.59 L13.16,7.59 C12.55,5.88 11.52,4.89 10.07,4.89 C8.84,4.89 7.89,5.69 7.89,7.03 C7.89,8.29 8.89,8.78 10.88,9.45 C12.57,10.03 14.38,10.6 14.38,12.91 C14.38,14.75 13.27,16.93 10.18,16.93 C9.18,16.93 8.17,16.69 7.46,16.39 L6.52,17 L6,17 L6,13.02 L6,13.02 Z"/><rect width="15" height="1" x="3" y="10"/></svg>',
"star": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" stroke-width="1.01" points="10 2 12.63 7.27 18.5 8.12 14.25 12.22 15.25 18 10 15.27 4.75 18 5.75 12.22 1.5 8.12 7.37 7.27"/></svg>',
"soundcloud": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.2,9.4c-0.4,0-0.8,0.1-1.101,0.2c-0.199-2.5-2.399-4.5-5-4.5c-0.6,0-1.2,0.1-1.7,0.3C9.2,5.5,9.1,5.6,9.1,5.6V15h8 c1.601,0,2.801-1.2,2.801-2.8C20,10.7,18.7,9.4,17.2,9.4L17.2,9.4z"/><rect width="1.5" height="8.5" x="6" y="6.5"/><rect width="1.5" height="7" x="3" y="8"/><rect width="1.5" height="5" y="10"/></svg>',
"sorting": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="7" y1="3.38" x2="7" y2="15.38"/><polyline fill="none" stroke="#000" points="10.18 12.75 7 15.93 3.83 12.76"/><line fill="none" stroke="#000" x1="13" y1="16.62" x2="13" y2="4.62"/><polyline fill="none" stroke="#000" points="9.82 7.25 13 4.07 16.17 7.24"/></svg>',
"social": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" stroke-width="1.1" x1="13.4" y1="14" x2="6.3" y2="10.7"/><line fill="none" stroke="#000" stroke-width="1.1" x1="13.5" y1="5.5" x2="6.5" y2="8.8"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="15.5" cy="4.6" r="2.3"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="15.5" cy="14.8" r="2.3"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="4.5" cy="9.8" r="2.3"/></svg>',
"signal": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m7.86,1.34l.2.81c-.79.19-1.54.51-2.24.93l-.43-.71c.77-.46,1.6-.81,2.47-1.02Zm4.28,0l-.2.81c.79.19,1.54.51,2.24.93l.43-.72c-.77-.46-1.6-.81-2.47-1.02h0ZM2.37,5.39c-.46.77-.81,1.6-1.02,2.47l.81.2c.19-.79.51-1.54.93-2.24l-.71-.43Zm-.45,4.61c0-.41.03-.81.09-1.21l-.83-.13c-.13.89-.13,1.79,0,2.67l.83-.13c-.06-.4-.09-.81-.09-1.21h0Zm12.69,7.63l-.43-.72c-.7.42-1.45.73-2.24.93l.2.81c.87-.21,1.7-.56,2.46-1.02h0Zm3.47-7.63c0,.41-.03.81-.09,1.21l.83.13c.13-.89.13-1.79,0-2.67l-.83.13c.06.4.09.81.09,1.21Zm.58,2.14l-.81-.2c-.19.79-.51,1.54-.93,2.24l.72.43c.46-.77.81-1.6,1.02-2.47h0Zm-7.44,5.85c-.8.12-1.62.12-2.42,0l-.13.83c.89.13,1.79.13,2.67,0l-.13-.83Zm5.29-3.2c-.48.65-1.06,1.23-1.71,1.71l.5.67c.72-.53,1.36-1.16,1.89-1.88l-.67-.5Zm-1.71-11.29c.65.48,1.23,1.06,1.71,1.71l.67-.5c-.53-.72-1.17-1.35-1.88-1.88l-.5.67Zm-11.29,1.71c.48-.65,1.06-1.23,1.71-1.71l-.5-.67c-.72.53-1.35,1.17-1.88,1.88l.67.5Zm14.14.18l-.72.43c.42.7.73,1.45.93,2.24l.81-.2c-.21-.87-.56-1.7-1.02-2.46h0Zm-8.84-3.38c.8-.12,1.62-.12,2.42,0l.13-.83c-.89-.13-1.79-.13-2.67,0l.13.83Zm-4.86,15.38l-1.73.4.4-1.73-.81-.19-.4,1.73c-.07.28.02.58.22.78s.5.29.78.22l1.73-.39-.19-.82Zm-1.96-2.26l.81.19.28-1.2c-.41-.68-.71-1.42-.9-2.19l-.81.2c.18.74.46,1.45.82,2.12l-.2.88Zm3.9,1.81l-1.19.28.19.81.88-.2c.67.36,1.38.64,2.12.82l.2-.81c-.77-.19-1.51-.5-2.19-.9h0ZM10,2.75c-2.63,0-5.06,1.43-6.34,3.74s-1.19,5.12.21,7.36l-.7,2.97,2.97-.7c2.61,1.64,5.96,1.46,8.37-.46s3.34-5.15,2.32-8.06c-1.02-2.91-3.77-4.85-6.85-4.85Z"/></svg>',
"sign-out": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="13 2 3 2 3 17 13 17 13 16 4 16 4 3 13 3 13 2"/><line stroke="#000" x1="7.96" y1="9.49" x2="16.96" y2="9.49"/><polyline fill="none" stroke="#000" points="14.17 6.31 17.35 9.48 14.17 12.66"/></svg>',
"sign-in": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="7 2 17 2 17 17 7 17 7 16 16 16 16 3 7 3 7 2"/><line stroke="#000" x1="3" y1="9.5" x2="12" y2="9.5"/><polyline fill="none" stroke="#000" points="9.2 6.33 12.37 9.5 9.2 12.67"/></svg>',
"shrink": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M2,18l6-6"/><polyline fill="none" stroke="#000" points="4 11.5 8.49 11.5 8.49 15.99"/><path fill="none" stroke="#000" stroke-width="1.1" d="M18,2l-6,6"/><polyline fill="none" stroke="#000" points="15.99 8.49 11.5 8.49 11.5 4"/></svg>',
"settings": '<svg width="20" height="20" viewBox="0 0 20 20"><ellipse fill="none" stroke="#000" cx="6.11" cy="3.55" rx="2.11" ry="2.15"/><ellipse fill="none" stroke="#000" cx="6.11" cy="15.55" rx="2.11" ry="2.15"/><circle fill="none" stroke="#000" cx="13.15" cy="9.55" r="2.15"/><rect width="3" height="1" x="1" y="3"/><rect width="8" height="1" x="10" y="3"/><rect width="8" height="1" x="1" y="9"/><rect width="3" height="1" x="15" y="9"/><rect width="3" height="1" x="1" y="15"/><rect width="8" height="1" x="10" y="15"/></svg>',
"server": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1" height="2" x="3" y="3"/><rect width="1" height="2" x="5" y="3"/><rect width="1" height="2" x="7" y="3"/><rect width="1" height="1" x="16" y="3"/><rect width="1" height="1" x="16" y="10"/><circle fill="none" stroke="#000" cx="9.9" cy="17.4" r="1.4"/><rect width="1" height="2" x="3" y="10"/><rect width="1" height="2" x="5" y="10"/><rect width="1" height="2" x="9.5" y="14"/><rect width="6" height="1" x="3" y="17"/><rect width="6" height="1" x="11" y="17"/><rect width="17" height="5" fill="none" stroke="#000" x="1.5" y="1.5"/><rect width="17" height="5" fill="none" stroke="#000" x="1.5" y="8.5"/></svg>',
"search": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9" cy="9" r="7"/><path fill="none" stroke="#000" stroke-width="1.1" d="M14,14 L18,18 L14,14 Z"/></svg>',
"rss": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="3.12" cy="16.8" r="1.85"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1.5,8.2 C1.78,8.18 2.06,8.16 2.35,8.16 C7.57,8.16 11.81,12.37 11.81,17.57 C11.81,17.89 11.79,18.19 11.76,18.5"/><path fill="none" stroke="#000" stroke-width="1.1" d="M1.5,2.52 C1.78,2.51 2.06,2.5 2.35,2.5 C10.72,2.5 17.5,9.24 17.5,17.57 C17.5,17.89 17.49,18.19 17.47,18.5"/></svg>',
"reply": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.7,13.11 C16.12,10.02 13.84,7.85 11.02,6.61 C10.57,6.41 9.75,6.13 9,5.91 L9,2 L1,9 L9,16 L9,12.13 C10.78,12.47 12.5,13.19 14.09,14.25 C17.13,16.28 18.56,18.54 18.56,18.54 C18.56,18.54 18.81,15.28 17.7,13.11 L17.7,13.11 Z M14.82,13.53 C13.17,12.4 11.01,11.4 8,10.92 L8,13.63 L2.55,9 L8,4.25 L8,6.8 C8.3,6.86 9.16,7.02 10.37,7.49 C13.3,8.65 15.54,10.96 16.65,13.08 C16.97,13.7 17.48,14.86 17.68,16 C16.87,15.05 15.73,14.15 14.82,13.53 L14.82,13.53 Z"/></svg>',
"refresh": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M17.08,11.15 C17.09,11.31 17.1,11.47 17.1,11.64 C17.1,15.53 13.94,18.69 10.05,18.69 C6.16,18.68 3,15.53 3,11.63 C3,7.74 6.16,4.58 10.05,4.58 C10.9,4.58 11.71,4.73 12.46,5"/><polyline fill="none" stroke="#000" points="9.9 2 12.79 4.89 9.79 7.9"/></svg>',
"reddit": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M19 9.05a2.56 2.56 0 0 0-2.56-2.56 2.59 2.59 0 0 0-1.88.82 10.63 10.63 0 0 0-4.14-1v-.08c.58-1.62 1.58-3.89 2.7-4.1.38-.08.77.12 1.19.57a1.15 1.15 0 0 0-.06.37 1.48 1.48 0 1 0 1.51-1.45 1.43 1.43 0 0 0-.76.19A2.29 2.29 0 0 0 12.91 1c-2.11.43-3.39 4.38-3.63 5.19 0 0 0 .11-.06.11a10.65 10.65 0 0 0-3.75 1A2.56 2.56 0 0 0 1 9.05a2.42 2.42 0 0 0 .72 1.76A5.18 5.18 0 0 0 1.24 13c0 3.66 3.92 6.64 8.73 6.64s8.74-3 8.74-6.64a5.23 5.23 0 0 0-.46-2.13A2.58 2.58 0 0 0 19 9.05zm-16.88 0a1.44 1.44 0 0 1 2.27-1.19 7.68 7.68 0 0 0-2.07 1.91 1.33 1.33 0 0 1-.2-.72zM10 18.4c-4.17 0-7.55-2.4-7.55-5.4S5.83 7.53 10 7.53 17.5 10 17.5 13s-3.38 5.4-7.5 5.4zm7.69-8.61a7.62 7.62 0 0 0-2.09-1.91 1.41 1.41 0 0 1 .84-.28 1.47 1.47 0 0 1 1.44 1.45 1.34 1.34 0 0 1-.21.72z"/><path d="M6.69 12.58a1.39 1.39 0 1 1 1.39-1.39 1.38 1.38 0 0 1-1.38 1.39z"/><path d="M14.26 11.2a1.39 1.39 0 1 1-1.39-1.39 1.39 1.39 0 0 1 1.39 1.39z"/><path d="M13.09 14.88a.54.54 0 0 1-.09.77 5.3 5.3 0 0 1-3.26 1.19 5.61 5.61 0 0 1-3.4-1.22.55.55 0 1 1 .73-.83 4.09 4.09 0 0 0 5.25 0 .56.56 0 0 1 .77.09z"/></svg>',
"receiver": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.01" d="M6.189,13.611C8.134,15.525 11.097,18.239 13.867,18.257C16.47,18.275 18.2,16.241 18.2,16.241L14.509,12.551L11.539,13.639L6.189,8.29L7.313,5.355L3.76,1.8C3.76,1.8 1.732,3.537 1.7,6.092C1.667,8.809 4.347,11.738 6.189,13.611"/></svg>',
"quote-right": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.27,7.79 C17.27,9.45 16.97,10.43 15.99,12.02 C14.98,13.64 13,15.23 11.56,15.97 L11.1,15.08 C12.34,14.2 13.14,13.51 14.02,11.82 C14.27,11.34 14.41,10.92 14.49,10.54 C14.3,10.58 14.09,10.6 13.88,10.6 C12.06,10.6 10.59,9.12 10.59,7.3 C10.59,5.48 12.06,4 13.88,4 C15.39,4 16.67,5.02 17.05,6.42 C17.19,6.82 17.27,7.27 17.27,7.79 L17.27,7.79 Z"/><path d="M8.68,7.79 C8.68,9.45 8.38,10.43 7.4,12.02 C6.39,13.64 4.41,15.23 2.97,15.97 L2.51,15.08 C3.75,14.2 4.55,13.51 5.43,11.82 C5.68,11.34 5.82,10.92 5.9,10.54 C5.71,10.58 5.5,10.6 5.29,10.6 C3.47,10.6 2,9.12 2,7.3 C2,5.48 3.47,4 5.29,4 C6.8,4 8.08,5.02 8.46,6.42 C8.6,6.82 8.68,7.27 8.68,7.79 L8.68,7.79 Z"/></svg>',
"question": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><circle cx="9.99" cy="14.24" r="1.05"/><path fill="none" stroke="#000" stroke-width="1.2" d="m7.72,7.61c0-3.04,4.55-3.06,4.55-.07,0,.95-.91,1.43-1.49,2.03-.48.49-.72.98-.78,1.65-.01.13-.02.24-.02.35"/></svg>',
"push": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="11" x2="10" y2="1"/><polyline fill="none" stroke="#000" points="6.5 6.5 4 6.5 4 19.5 16 19.5 16 6.5 13.5 6.5"/><polyline fill="none" stroke="#000" points="6.82 3.88 10 .71 13.17 3.88"/></svg>',
"pull": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="11" x2="10" y2="2"/><polyline fill="none" stroke="#000" points="6.5 5.5 4 5.5 4 18.5 16 18.5 16 5.5 13.5 5.5"/><polyline fill="none" stroke="#000" points="13.18 8.2 10 11.38 6.83 8.21"/></svg>',
"print": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="4.5 13.5 1.5 13.5 1.5 6.5 18.5 6.5 18.5 13.5 15.5 13.5"/><polyline fill="none" stroke="#000" points="15.5 6.5 15.5 2.5 4.5 2.5 4.5 6.5"/><rect width="11" height="6" fill="none" stroke="#000" x="4.5" y="11.5"/><rect width="8" height="1" x="6" y="13"/><rect width="8" height="1" x="6" y="15"/></svg>',
"plus": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1" height="17" x="9" y="1"/><rect width="17" height="1" x="1" y="9"/></svg>',
"plus-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9.5" cy="9.5" r="9"/><line fill="none" stroke="#000" x1="9.5" y1="5" x2="9.5" y2="14"/><line fill="none" stroke="#000" x1="5" y1="9.5" x2="14" y2="9.5"/></svg>',
"play": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="6.5,5 14.5,10 6.5,15"/></svg>',
"play-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" stroke-width="1.1" points="8.5 7 13.5 10 8.5 13"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/></svg>',
"pinterest": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10.21,1 C5.5,1 3,4.16 3,7.61 C3,9.21 3.85,11.2 5.22,11.84 C5.43,11.94 5.54,11.89 5.58,11.69 C5.62,11.54 5.8,10.8 5.88,10.45 C5.91,10.34 5.89,10.24 5.8,10.14 C5.36,9.59 5,8.58 5,7.65 C5,5.24 6.82,2.91 9.93,2.91 C12.61,2.91 14.49,4.74 14.49,7.35 C14.49,10.3 13,12.35 11.06,12.35 C9.99,12.35 9.19,11.47 9.44,10.38 C9.75,9.08 10.35,7.68 10.35,6.75 C10.35,5.91 9.9,5.21 8.97,5.21 C7.87,5.21 6.99,6.34 6.99,7.86 C6.99,8.83 7.32,9.48 7.32,9.48 C7.32,9.48 6.24,14.06 6.04,14.91 C5.7,16.35 6.08,18.7 6.12,18.9 C6.14,19.01 6.26,19.05 6.33,18.95 C6.44,18.81 7.74,16.85 8.11,15.44 C8.24,14.93 8.79,12.84 8.79,12.84 C9.15,13.52 10.19,14.09 11.29,14.09 C14.58,14.09 16.96,11.06 16.96,7.3 C16.94,3.7 14,1 10.21,1"/></svg>',
"phone": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M15.5,17 C15.5,17.8 14.8,18.5 14,18.5 L7,18.5 C6.2,18.5 5.5,17.8 5.5,17 L5.5,3 C5.5,2.2 6.2,1.5 7,1.5 L14,1.5 C14.8,1.5 15.5,2.2 15.5,3 L15.5,17 L15.5,17 L15.5,17 Z"/><circle cx="10.5" cy="16.5" r=".8"/></svg>',
"phone-landscape": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M17,5.5 C17.8,5.5 18.5,6.2 18.5,7 L18.5,14 C18.5,14.8 17.8,15.5 17,15.5 L3,15.5 C2.2,15.5 1.5,14.8 1.5,14 L1.5,7 C1.5,6.2 2.2,5.5 3,5.5 L17,5.5 L17,5.5 L17,5.5 Z"/><circle cx="3.8" cy="10.5" r=".8"/></svg>',
"pencil": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M17.25,6.01 L7.12,16.1 L3.82,17.2 L5.02,13.9 L15.12,3.88 C15.71,3.29 16.66,3.29 17.25,3.88 C17.83,4.47 17.83,5.42 17.25,6.01 L17.25,6.01 Z"/><path fill="none" stroke="#000" d="M15.98,7.268 L13.851,5.148"/></svg>',
"paint-bucket": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="m6.42,2.16l5.28,5.28"/><path d="m18.49,11.83s1.51,2.06,1.51,3.36c0,.92-.76,1.64-1.51,1.64h0c-.75,0-1.49-.72-1.49-1.64,0-1.3,1.49-3.36,1.49-3.36h0Z"/><line fill="none" stroke="#000" x1="1.26" y1="10.5" x2="16" y2="10.5"/><polygon fill="none" stroke="#000" stroke-width="1.1" points="10.2 1.55 17.6 8.93 8.08 18.45 .7 11.07 10.2 1.55"/></svg>',
"nut": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="2.5,5.7 10,1.3 17.5,5.7 17.5,14.3 10,18.7 2.5,14.3"/><circle fill="none" stroke="#000" cx="10" cy="10" r="3.5"/></svg>',
"move": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="4,5 1,5 1,9 2,9 2,6 4,6"/><polygon points="1,16 2,16 2,18 4,18 4,19 1,19"/><polygon points="14,16 14,19 11,19 11,18 13,18 13,16"/><rect width="13" height="13" fill="none" stroke="#000" x="5.5" y="1.5"/><rect width="1" height="3" x="1" y="11"/><rect width="3" height="1" x="6" y="18"/></svg>',
"more": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="3" cy="10" r="2"/><circle cx="10" cy="10" r="2"/><circle cx="17" cy="10" r="2"/></svg>',
"more-vertical": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="3" r="2"/><circle cx="10" cy="10" r="2"/><circle cx="10" cy="17" r="2"/></svg>',
"minus": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="18" height="1" x="1" y="9"/></svg>',
"minus-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9.5" cy="9.5" r="9"/><line fill="none" stroke="#000" x1="5" y1="9.5" x2="14" y2="9.5"/></svg>',
"microsoft": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m2,2h7.58v7.58H2V2Zm8.42,0h7.58v7.58h-7.58V2ZM2,10.42h7.58v7.58H2v-7.58Zm8.42,0h7.58v7.58h-7.58"/></svg>',
"microphone": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="16.44" x2="10" y2="18.5"/><line fill="none" stroke="#000" x1="7" y1="18.5" x2="13" y2="18.5"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.5 4.89v5.87a3.5 3.5 0 0 1-7 0V4.89a3.5 3.5 0 0 1 7 0z"/><path fill="none" stroke="#000" stroke-width="1.1" d="M15.5 10.36V11a5.5 5.5 0 0 1-11 0v-.6"/></svg>',
"menu": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="16" height="1" x="2" y="4"/><rect width="16" height="1" x="2" y="9"/><rect width="16" height="1" x="2" y="14"/></svg>',
"mastodon": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m18.5,6.87c0-3.95-2.59-5.11-2.59-5.11-1.31-.6-3.55-.85-5.88-.87h-.06c-2.33.02-4.57.27-5.88.87,0,0-2.59,1.16-2.59,5.11,0,.91-.02,1.99.01,3.14.09,3.87.71,7.68,4.28,8.62,1.65.44,3.06.53,4.2.47,2.07-.11,3.23-.74,3.23-.74l-.07-1.5s-1.48.47-3.14.41c-1.64-.06-3.38-.18-3.64-2.2-.02-.18-.04-.37-.04-.57,0,0,1.61.39,3.66.49,1.25.06,2.42-.07,3.61-.22,2.28-.27,4.27-1.68,4.52-2.97.39-2.02.36-4.94.36-4.94Zm-3.05,5.09h-1.9v-4.65c0-.98-.41-1.48-1.24-1.48-.91,0-1.37.59-1.37,1.76v2.54h-1.89v-2.54c0-1.17-.46-1.76-1.37-1.76-.82,0-1.24.5-1.24,1.48v4.65h-1.9v-4.79c0-.98.25-1.76.75-2.33.52-.58,1.19-.87,2.03-.87.97,0,1.71.37,2.19,1.12l.47.79.47-.79c.49-.75,1.22-1.12,2.19-1.12.84,0,1.51.29,2.03.87.5.58.75,1.35.75,2.33v4.79Z"/></svg>',
"mail": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="1.4,6.5 10,11 18.6,6.5"/><path d="M 1,4 1,16 19,16 19,4 1,4 Z M 18,15 2,15 2,5 18,5 18,15 Z"/></svg>',
"lock": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="10" fill="none" stroke="#000" x="3.5" y="8.5"/><path fill="none" stroke="#000" d="M6.5,8 L6.5,4.88 C6.5,3.01 8.07,1.5 10,1.5 C11.93,1.5 13.5,3.01 13.5,4.88 L13.5,8"/></svg>',
"location": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.01" d="M10,0.5 C6.41,0.5 3.5,3.39 3.5,6.98 C3.5,11.83 10,19 10,19 C10,19 16.5,11.83 16.5,6.98 C16.5,3.39 13.59,0.5 10,0.5 L10,0.5 Z"/><circle fill="none" stroke="#000" cx="10" cy="6.8" r="2.3"/></svg>',
"list": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="12" height="1" x="6" y="4"/><rect width="12" height="1" x="6" y="9"/><rect width="12" height="1" x="6" y="14"/><rect width="2" height="1" x="2" y="4"/><rect width="2" height="1" x="2" y="9"/><rect width="2" height="1" x="2" y="14"/></svg>',
"linkedin": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M5.77,17.89 L5.77,7.17 L2.21,7.17 L2.21,17.89 L5.77,17.89 L5.77,17.89 Z M3.99,5.71 C5.23,5.71 6.01,4.89 6.01,3.86 C5.99,2.8 5.24,2 4.02,2 C2.8,2 2,2.8 2,3.85 C2,4.88 2.77,5.7 3.97,5.7 L3.99,5.7 L3.99,5.71 L3.99,5.71 Z"/><path d="M7.75,17.89 L11.31,17.89 L11.31,11.9 C11.31,11.58 11.33,11.26 11.43,11.03 C11.69,10.39 12.27,9.73 13.26,9.73 C14.55,9.73 15.06,10.71 15.06,12.15 L15.06,17.89 L18.62,17.89 L18.62,11.74 C18.62,8.45 16.86,6.92 14.52,6.92 C12.6,6.92 11.75,7.99 11.28,8.73 L11.3,8.73 L11.3,7.17 L7.75,7.17 C7.79,8.17 7.75,17.89 7.75,17.89 L7.75,17.89 L7.75,17.89 Z"/></svg>',
"link": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M10.625,12.375 L7.525,15.475 C6.825,16.175 5.925,16.175 5.225,15.475 L4.525,14.775 C3.825,14.074 3.825,13.175 4.525,12.475 L7.625,9.375"/><path fill="none" stroke="#000" stroke-width="1.1" d="M9.325,7.375 L12.425,4.275 C13.125,3.575 14.025,3.575 14.724,4.275 L15.425,4.975 C16.125,5.675 16.125,6.575 15.425,7.275 L12.325,10.375"/><path fill="none" stroke="#000" stroke-width="1.1" d="M7.925,11.875 L11.925,7.975"/></svg>',
"link-external": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="15 10.5 15 17 3 17 3 5 9.5 5"/><line fill="none" stroke="#000" x1="8.22" y1="11.79" x2="17.01" y2="2.99"/><polyline fill="none" stroke="#000" points="12.5 3 17 3 17 7.5"/></svg>',
"lifesaver": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="10" cy="10" r="9"/><circle fill="none" stroke="#000" cx="10" cy="10" r="5"/><line fill="none" stroke="#000" stroke-width="1.1" x1="5.17" y1="2.39" x2="8.11" y2="5.33"/><line fill="none" stroke="#000" stroke-width="1.1" x1="5.33" y1="8.11" x2="2.39" y2="5.17"/><line fill="none" stroke="#000" stroke-width="1.1" x1="14.83" y1="17.61" x2="11.89" y2="14.67"/><line fill="none" stroke="#000" stroke-width="1.1" x1="14.67" y1="11.89" x2="17.61" y2="14.83"/><line fill="none" stroke="#000" stroke-width="1.1" x1="17.61" y1="5.17" x2="14.67" y2="8.11"/><line fill="none" stroke="#000" stroke-width="1.1" x1="11.89" y1="5.33" x2="14.83" y2="2.39"/><line fill="none" stroke="#000" stroke-width="1.1" x1="8.11" y1="14.67" x2="5.17" y2="17.61"/><line fill="none" stroke="#000" stroke-width="1.1" x1="2.39" y1="14.83" x2="5.33" y2="11.89"/></svg>',
"laptop": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="20" height="1" y="16"/><rect width="15" height="10" fill="none" stroke="#000" x="2.5" y="4.5"/></svg>',
"joomla": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M7.8,13.4l1.7-1.7L5.9,8c-0.6-0.5-0.6-1.5,0-2c0.6-0.6,1.4-0.6,2,0l1.7-1.7c-1-1-2.3-1.3-3.6-1C5.8,2.2,4.8,1.4,3.7,1.4 c-1.3,0-2.3,1-2.3,2.3c0,1.1,0.8,2,1.8,2.3c-0.4,1.3-0.1,2.8,1,3.8L7.8,13.4L7.8,13.4z"/><path d="M10.2,4.3c1-1,2.5-1.4,3.8-1c0.2-1.1,1.1-2,2.3-2c1.3,0,2.3,1,2.3,2.3c0,1.2-0.9,2.2-2,2.3c0.4,1.3,0,2.8-1,3.8L13.9,8 c0.6-0.5,0.6-1.5,0-2c-0.5-0.6-1.5-0.6-2,0L8.2,9.7L6.5,8"/><path d="M14.1,16.8c-1.3,0.4-2.8,0.1-3.8-1l1.7-1.7c0.6,0.6,1.5,0.6,2,0c0.5-0.6,0.6-1.5,0-2l-3.7-3.7L12,6.7l3.7,3.7 c1,1,1.3,2.4,1,3.6c1.1,0.2,2,1.1,2,2.3c0,1.3-1,2.3-2.3,2.3C15.2,18.6,14.3,17.8,14.1,16.8"/><path d="M13.2,12.2l-3.7,3.7c-1,1-2.4,1.3-3.6,1c-0.2,1-1.2,1.8-2.2,1.8c-1.3,0-2.3-1-2.3-2.3c0-1.1,0.8-2,1.8-2.3 c-0.3-1.3,0-2.7,1-3.7l1.7,1.7c-0.6,0.6-0.6,1.5,0,2c0.6,0.6,1.4,0.6,2,0l3.7-3.7"/></svg>',
"italic": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M12.63,5.48 L10.15,14.52 C10,15.08 10.37,15.25 11.92,15.3 L11.72,16 L6,16 L6.2,15.31 C7.78,15.26 8.19,15.09 8.34,14.53 L10.82,5.49 C10.97,4.92 10.63,4.76 9.09,4.71 L9.28,4 L15,4 L14.81,4.69 C13.23,4.75 12.78,4.91 12.63,5.48 L12.63,5.48 Z"/></svg>',
"instagram": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M13.55,1H6.46C3.45,1,1,3.44,1,6.44v7.12c0,3,2.45,5.44,5.46,5.44h7.08c3.02,0,5.46-2.44,5.46-5.44V6.44 C19.01,3.44,16.56,1,13.55,1z M17.5,14c0,1.93-1.57,3.5-3.5,3.5H6c-1.93,0-3.5-1.57-3.5-3.5V6c0-1.93,1.57-3.5,3.5-3.5h8 c1.93,0,3.5,1.57,3.5,3.5V14z"/><circle cx="14.87" cy="5.26" r="1.09"/><path d="M10.03,5.45c-2.55,0-4.63,2.06-4.63,4.6c0,2.55,2.07,4.61,4.63,4.61c2.56,0,4.63-2.061,4.63-4.61 C14.65,7.51,12.58,5.45,10.03,5.45L10.03,5.45L10.03,5.45z M10.08,13c-1.66,0-3-1.34-3-2.99c0-1.65,1.34-2.99,3-2.99s3,1.34,3,2.99 C13.08,11.66,11.74,13,10.08,13L10.08,13L10.08,13z"/></svg>',
"info": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"/><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/></svg>',
"image": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="16.1" cy="6.1" r="1.1"/><rect width="19" height="15" fill="none" stroke="#000" x=".5" y="2.5"/><polyline fill="none" stroke="#000" stroke-width="1.01" points="4,13 8,9 13,14"/><polyline fill="none" stroke="#000" stroke-width="1.01" points="11,12 12.5,10.5 16,14"/></svg>',
"home": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon points="18.65 11.35 10 2.71 1.35 11.35 0.65 10.65 10 1.29 19.35 10.65"/><polygon points="15 4 18 4 18 7 17 7 17 5 15 5"/><polygon points="3 11 4 11 4 18 7 18 7 12 12 12 12 18 16 18 16 11 17 11 17 19 11 19 11 13 8 13 8 19 3 19"/></svg>',
"history": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="#000" points="1 2 2 2 2 6 6 6 6 7 1 7 1 2"/><path fill="none" stroke="#000" stroke-width="1.1" d="M2.1,6.548 C3.391,3.29 6.746,1 10.5,1 C15.5,1 19.5,5 19.5,10 C19.5,15 15.5,19 10.5,19 C5.5,19 1.5,15 1.5,10"/><rect width="1" height="7" x="9" y="4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.018,14.197 L9.445,10.625"/></svg>',
"heart": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.03" d="M10,4 C10,4 8.1,2 5.74,2 C3.38,2 1,3.55 1,6.73 C1,8.84 2.67,10.44 2.67,10.44 L10,18 L17.33,10.44 C17.33,10.44 19,8.84 19,6.73 C19,3.55 16.62,2 14.26,2 C11.9,2 10,4 10,4 L10,4 Z"/></svg>',
"hashtag": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M15.431,8 L15.661,7 L12.911,7 L13.831,3 L12.901,3 L11.98,7 L9.29,7 L10.21,3 L9.281,3 L8.361,7 L5.23,7 L5,8 L8.13,8 L7.21,12 L4.23,12 L4,13 L6.98,13 L6.061,17 L6.991,17 L7.911,13 L10.601,13 L9.681,17 L10.611,17 L11.531,13 L14.431,13 L14.661,12 L11.76,12 L12.681,8 L15.431,8 Z M10.831,12 L8.141,12 L9.061,8 L11.75,8 L10.831,12 Z"/></svg>',
"happy": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="13" cy="7" r="1"/><circle cx="7" cy="7" r="1"/><circle fill="none" stroke="#000" cx="10" cy="10" r="8.5"/><path fill="none" stroke="#000" d="M14.6,11.4 C13.9,13.3 12.1,14.5 10,14.5 C7.9,14.5 6.1,13.3 5.4,11.4"/></svg>',
"grid": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="3" height="3" x="2" y="2"/><rect width="3" height="3" x="8" y="2"/><rect width="3" height="3" x="14" y="2"/><rect width="3" height="3" x="2" y="8"/><rect width="3" height="3" x="8" y="8"/><rect width="3" height="3" x="14" y="8"/><rect width="3" height="3" x="2" y="14"/><rect width="3" height="3" x="8" y="14"/><rect width="3" height="3" x="14" y="14"/></svg>',
"google": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17.86,9.09 C18.46,12.12 17.14,16.05 13.81,17.56 C9.45,19.53 4.13,17.68 2.47,12.87 C0.68,7.68 4.22,2.42 9.5,2.03 C11.57,1.88 13.42,2.37 15.05,3.65 C15.22,3.78 15.37,3.93 15.61,4.14 C14.9,4.81 14.23,5.45 13.5,6.14 C12.27,5.08 10.84,4.72 9.28,4.98 C8.12,5.17 7.16,5.76 6.37,6.63 C4.88,8.27 4.62,10.86 5.76,12.82 C6.95,14.87 9.17,15.8 11.57,15.25 C13.27,14.87 14.76,13.33 14.89,11.75 L10.51,11.75 L10.51,9.09 L17.86,9.09 L17.86,9.09 Z"/></svg>',
"gitter": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1.531" height="11.471" x="3.5" y="1"/><rect width="1.529" height="15.294" x="7.324" y="4.059"/><rect width="1.527" height="15.294" x="11.148" y="4.059"/><rect width="1.529" height="8.412" x="14.971" y="4.059"/></svg>',
"github": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10,1 C5.03,1 1,5.03 1,10 C1,13.98 3.58,17.35 7.16,18.54 C7.61,18.62 7.77,18.34 7.77,18.11 C7.77,17.9 7.76,17.33 7.76,16.58 C5.26,17.12 4.73,15.37 4.73,15.37 C4.32,14.33 3.73,14.05 3.73,14.05 C2.91,13.5 3.79,13.5 3.79,13.5 C4.69,13.56 5.17,14.43 5.17,14.43 C5.97,15.8 7.28,15.41 7.79,15.18 C7.87,14.6 8.1,14.2 8.36,13.98 C6.36,13.75 4.26,12.98 4.26,9.53 C4.26,8.55 4.61,7.74 5.19,7.11 C5.1,6.88 4.79,5.97 5.28,4.73 C5.28,4.73 6.04,4.49 7.75,5.65 C8.47,5.45 9.24,5.35 10,5.35 C10.76,5.35 11.53,5.45 12.25,5.65 C13.97,4.48 14.72,4.73 14.72,4.73 C15.21,5.97 14.9,6.88 14.81,7.11 C15.39,7.74 15.73,8.54 15.73,9.53 C15.73,12.99 13.63,13.75 11.62,13.97 C11.94,14.25 12.23,14.8 12.23,15.64 C12.23,16.84 12.22,17.81 12.22,18.11 C12.22,18.35 12.38,18.63 12.84,18.54 C16.42,17.35 19,13.98 19,10 C19,5.03 14.97,1 10,1 L10,1 Z"/></svg>',
"github-alt": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M10,0.5 C4.75,0.5 0.5,4.76 0.5,10.01 C0.5,15.26 4.75,19.51 10,19.51 C15.24,19.51 19.5,15.26 19.5,10.01 C19.5,4.76 15.25,0.5 10,0.5 L10,0.5 Z M12.81,17.69 C12.81,17.69 12.81,17.7 12.79,17.69 C12.47,17.75 12.35,17.59 12.35,17.36 L12.35,16.17 C12.35,15.45 12.09,14.92 11.58,14.56 C12.2,14.51 12.77,14.39 13.26,14.21 C13.87,13.98 14.36,13.69 14.74,13.29 C15.42,12.59 15.76,11.55 15.76,10.17 C15.76,9.25 15.45,8.46 14.83,7.8 C15.1,7.08 15.07,6.29 14.75,5.44 L14.51,5.42 C14.34,5.4 14.06,5.46 13.67,5.61 C13.25,5.78 12.79,6.03 12.31,6.35 C11.55,6.16 10.81,6.05 10.09,6.05 C9.36,6.05 8.61,6.15 7.88,6.35 C7.28,5.96 6.75,5.68 6.26,5.54 C6.07,5.47 5.9,5.44 5.78,5.44 L5.42,5.44 C5.06,6.29 5.04,7.08 5.32,7.8 C4.7,8.46 4.4,9.25 4.4,10.17 C4.4,11.94 4.96,13.16 6.08,13.84 C6.53,14.13 7.05,14.32 7.69,14.43 C8.03,14.5 8.32,14.54 8.55,14.55 C8.07,14.89 7.82,15.42 7.82,16.16 L7.82,17.51 C7.8,17.69 7.7,17.8 7.51,17.8 C4.21,16.74 1.82,13.65 1.82,10.01 C1.82,5.5 5.49,1.83 10,1.83 C14.5,1.83 18.17,5.5 18.17,10.01 C18.18,13.53 15.94,16.54 12.81,17.69 L12.81,17.69 Z"/></svg>',
"git-fork": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="6" cy="3" r="1.79"/><circle fill="none" stroke="#000" cx="14" cy="3" r="1.79"/><circle fill="none" stroke="#000" cx="10" cy="17" r="1.79"/><path fill="none" stroke="#000" d="m6,4.78v1.99c0,2.63,4,3.66,4,6.75,0,1.55.01,1.24.01,1.24,0-.18,0,.31,0-1.24,0-3.09,3.99-4.12,3.99-6.75v-1.99"/></svg>',
"git-branch": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="m13.5,8c0,2.41-1.57,2.87-3.44,3.25-1.47.29-3.56.81-3.56,3.75V5"/><circle fill="none" stroke="#000" cx="6.5" cy="3" r="1.79"/><circle fill="none" stroke="#000" cx="13.5" cy="6" r="1.79"/><circle fill="none" stroke="#000" cx="6.5" cy="17" r="1.79"/></svg>',
"future": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline points="19 2 18 2 18 6 14 6 14 7 19 7 19 2"/><path fill="none" stroke="#000" stroke-width="1.1" d="M18,6.548 C16.709,3.29 13.354,1 9.6,1 C4.6,1 0.6,5 0.6,10 C0.6,15 4.6,19 9.6,19 C14.6,19 18.6,15 18.6,10"/><rect width="1" height="7" x="9" y="4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.018,14.197 L9.445,10.625"/></svg>',
"foursquare": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M15.23,2 C15.96,2 16.4,2.41 16.5,2.86 C16.57,3.15 16.56,3.44 16.51,3.73 C16.46,4.04 14.86,11.72 14.75,12.03 C14.56,12.56 14.16,12.82 13.61,12.83 C13.03,12.84 11.09,12.51 10.69,13 C10.38,13.38 7.79,16.39 6.81,17.53 C6.61,17.76 6.4,17.96 6.08,17.99 C5.68,18.04 5.29,17.87 5.17,17.45 C5.12,17.28 5.1,17.09 5.1,16.91 C5.1,12.4 4.86,7.81 5.11,3.31 C5.17,2.5 5.81,2.12 6.53,2 L15.23,2 L15.23,2 Z M9.76,11.42 C9.94,11.19 10.17,11.1 10.45,11.1 L12.86,11.1 C13.12,11.1 13.31,10.94 13.36,10.69 C13.37,10.64 13.62,9.41 13.74,8.83 C13.81,8.52 13.53,8.28 13.27,8.28 C12.35,8.29 11.42,8.28 10.5,8.28 C9.84,8.28 9.83,7.69 9.82,7.21 C9.8,6.85 10.13,6.55 10.5,6.55 C11.59,6.56 12.67,6.55 13.76,6.55 C14.03,6.55 14.23,6.4 14.28,6.14 C14.34,5.87 14.67,4.29 14.67,4.29 C14.67,4.29 14.82,3.74 14.19,3.74 L7.34,3.74 C7,3.75 6.84,4.02 6.84,4.33 C6.84,7.58 6.85,14.95 6.85,14.99 C6.87,15 8.89,12.51 9.76,11.42 L9.76,11.42 Z"/></svg>',
"forward": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M2.47,13.11 C4.02,10.02 6.27,7.85 9.04,6.61 C9.48,6.41 10.27,6.13 11,5.91 L11,2 L18.89,9 L11,16 L11,12.13 C9.25,12.47 7.58,13.19 6.02,14.25 C3.03,16.28 1.63,18.54 1.63,18.54 C1.63,18.54 1.38,15.28 2.47,13.11 L2.47,13.11 Z M5.3,13.53 C6.92,12.4 9.04,11.4 12,10.92 L12,13.63 L17.36,9 L12,4.25 L12,6.8 C11.71,6.86 10.86,7.02 9.67,7.49 C6.79,8.65 4.58,10.96 3.49,13.08 C3.18,13.7 2.68,14.87 2.49,16 C3.28,15.05 4.4,14.15 5.3,13.53 L5.3,13.53 Z"/></svg>',
"folder": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="9.5 5.5 8.5 3.5 1.5 3.5 1.5 16.5 18.5 16.5 18.5 5.5"/></svg>',
"flickr": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="5.5" cy="9.5" r="3.5"/><circle cx="14.5" cy="9.5" r="3.5"/></svg>',
"file": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="17" fill="none" stroke="#000" x="3.5" y="1.5"/></svg>',
"file-text": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="17" fill="none" stroke="#000" x="3.5" y="1.5"/><line fill="none" stroke="#000" x1="6" y1="12.5" x2="12" y2="12.5"/><line fill="none" stroke="#000" x1="6" y1="8.5" x2="14" y2="8.5"/><line fill="none" stroke="#000" x1="6" y1="6.5" x2="14" y2="6.5"/><line fill="none" stroke="#000" x1="6" y1="10.5" x2="14" y2="10.5"/></svg>',
"file-pdf": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="13" height="17" fill="none" stroke="#000" x="3.5" y="1.5"/><path d="M14.65 11.67c-.48.3-1.37-.19-1.79-.37a4.65 4.65 0 0 1 1.49.06c.35.1.36.28.3.31zm-6.3.06l.43-.79a14.7 14.7 0 0 0 .75-1.64 5.48 5.48 0 0 0 1.25 1.55l.2.15a16.36 16.36 0 0 0-2.63.73zM9.5 5.32c.2 0 .32.5.32.97a1.99 1.99 0 0 1-.23 1.04 5.05 5.05 0 0 1-.17-1.3s0-.71.08-.71zm-3.9 9a4.35 4.35 0 0 1 1.21-1.46l.24-.22a4.35 4.35 0 0 1-1.46 1.68zm9.23-3.3a2.05 2.05 0 0 0-1.32-.3 11.07 11.07 0 0 0-1.58.11 4.09 4.09 0 0 1-.74-.5 5.39 5.39 0 0 1-1.32-2.06 10.37 10.37 0 0 0 .28-2.62 1.83 1.83 0 0 0-.07-.25.57.57 0 0 0-.52-.4H9.4a.59.59 0 0 0-.6.38 6.95 6.95 0 0 0 .37 3.14c-.26.63-1 2.12-1 2.12-.3.58-.57 1.08-.82 1.5l-.8.44A3.11 3.11 0 0 0 5 14.16a.39.39 0 0 0 .15.42l.24.13c1.15.56 2.28-1.74 2.66-2.42a23.1 23.1 0 0 1 3.59-.85 4.56 4.56 0 0 0 2.91.8.5.5 0 0 0 .3-.21 1.1 1.1 0 0 0 .12-.75.84.84 0 0 0-.14-.25z"/></svg>',
"file-edit": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M18.65,1.68 C18.41,1.45 18.109,1.33 17.81,1.33 C17.499,1.33 17.209,1.45 16.98,1.68 L8.92,9.76 L8,12.33 L10.55,11.41 L18.651,3.34 C19.12,2.87 19.12,2.15 18.65,1.68 L18.65,1.68 L18.65,1.68 Z"/><polyline fill="none" stroke="#000" points="16.5 8.482 16.5 18.5 3.5 18.5 3.5 1.5 14.211 1.5"/></svg>',
"facebook": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M11,10h2.6l0.4-3H11V5.3c0-0.9,0.2-1.5,1.5-1.5H14V1.1c-0.3,0-1-0.1-2.1-0.1C9.6,1,8,2.4,8,5v2H5.5v3H8v8h3V10z"/></svg>',
"eye": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="10" cy="10" r="3.45"/><path fill="none" stroke="#000" d="m19.5,10c-2.4,3.66-5.26,7-9.5,7h0,0,0c-4.24,0-7.1-3.34-9.49-7C2.89,6.34,5.75,3,9.99,3h0,0,0c4.25,0,7.11,3.34,9.5,7Z"/></svg>',
"eye-slash": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="m7.56,7.56c.62-.62,1.49-1.01,2.44-1.01,1.91,0,3.45,1.54,3.45,3.45,0,.95-.39,1.82-1.01,2.44"/><path fill="none" stroke="#000" d="m19.5,10c-2.4,3.66-5.26,7-9.5,7h0,0,0c-4.24,0-7.1-3.34-9.49-7C2.89,6.34,5.75,3,9.99,3h0,0,0c4.25,0,7.11,3.34,9.5,7Z"/><line fill="none" stroke="#000" x1="2.5" y1="2.5" x2="17.5" y2="17.5"/></svg>',
"expand": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M2.48,17.52l6.52-6.52"/><polyline fill="none" stroke="#000" points="6.97 17.52 2.48 17.52 2.48 13.03"/><path fill="none" stroke="#000" stroke-width="1.1" d="M17.52,2.48l-6.52,6.52"/><polyline fill="none" stroke="#000" points="13.03 2.48 17.52 2.48 17.52 6.97"/></svg>',
"etsy": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M8,4.26C8,4.07,8,4,8.31,4h4.46c.79,0,1.22.67,1.53,1.91l.25,1h.76c.14-2.82.26-4,.26-4S13.65,3,12.52,3H6.81L3.75,2.92v.84l1,.2c.73.11.9.27,1,1,0,0,.06,2,.06,5.17s-.06,5.14-.06,5.14c0,.59-.23.81-1,.94l-1,.2v.84l3.06-.1h5.11c1.15,0,3.82.1,3.82.1,0-.7.45-3.88.51-4.22h-.73l-.76,1.69a2.25,2.25,0,0,1-2.45,1.47H9.4c-1,0-1.44-.4-1.44-1.24V10.44s2.16,0,2.86.06c.55,0,.85.19,1.06,1l.23,1H13L12.9,9.94,13,7.41h-.85l-.28,1.13c-.16.74-.28.84-1,1-1,.1-2.89.09-2.89.09Z"/></svg>',
"dribbble": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.4" d="M1.3,8.9c0,0,5,0.1,8.6-1c1.4-0.4,2.6-0.9,4-1.9 c1.4-1.1,2.5-2.5,2.5-2.5"/><path fill="none" stroke="#000" stroke-width="1.4" d="M3.9,16.6c0,0,1.7-2.8,3.5-4.2 c1.8-1.3,4-2,5.7-2.2C16,10,19,10.6,19,10.6"/><path fill="none" stroke="#000" stroke-width="1.4" d="M6.9,1.6c0,0,3.3,4.6,4.2,6.8 c0.4,0.9,1.3,3.1,1.9,5.2c0.6,2,0.9,4.4,0.9,4.4"/><circle fill="none" stroke="#000" stroke-width="1.4" cx="10" cy="10" r="9"/></svg>',
"download": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="2.09" x2="10" y2="14.09"/><polyline fill="none" stroke="#000" points="6.16 10.62 10 14.46 13.84 10.62"/><line stroke="#000" x1="3.5" y1="17.5" x2="16.5" y2="17.5"/></svg>',
"discord": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M16.074,4.361a14.243,14.243,0,0,0-3.61-1.134,10.61,10.61,0,0,0-.463.96,13.219,13.219,0,0,0-4,0,10.138,10.138,0,0,0-.468-.96A14.206,14.206,0,0,0,3.919,4.364,15.146,15.146,0,0,0,1.324,14.5a14.435,14.435,0,0,0,4.428,2.269A10.982,10.982,0,0,0,6.7,15.21a9.294,9.294,0,0,1-1.494-.727c.125-.093.248-.19.366-.289a10.212,10.212,0,0,0,8.854,0c.119.1.242.2.366.289a9.274,9.274,0,0,1-1.5.728,10.8,10.8,0,0,0,.948,1.562,14.419,14.419,0,0,0,4.431-2.27A15.128,15.128,0,0,0,16.074,4.361Zm-8.981,8.1a1.7,1.7,0,0,1-1.573-1.79A1.689,1.689,0,0,1,7.093,8.881a1.679,1.679,0,0,1,1.573,1.791A1.687,1.687,0,0,1,7.093,12.462Zm5.814,0a1.7,1.7,0,0,1-1.573-1.79,1.689,1.689,0,0,1,1.573-1.791,1.679,1.679,0,0,1,1.573,1.791A1.688,1.688,0,0,1,12.907,12.462Z"/></svg>',
"desktop": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="1" height="2" x="8" y="15"/><rect width="1" height="2" x="11" y="15"/><rect width="10" height="1" x="5" y="16"/><rect width="17" height="11" fill="none" stroke="#000" x="1.5" y="3.5"/></svg>',
"database": '<svg width="20" height="20" viewBox="0 0 20 20"><ellipse fill="none" stroke="#000" cx="10" cy="4.64" rx="7.5" ry="3.14"/><path fill="none" stroke="#000" d="M17.5,8.11 C17.5,9.85 14.14,11.25 10,11.25 C5.86,11.25 2.5,9.84 2.5,8.11"/><path fill="none" stroke="#000" d="M17.5,11.25 C17.5,12.99 14.14,14.39 10,14.39 C5.86,14.39 2.5,12.98 2.5,11.25"/><path fill="none" stroke="#000" d="M17.49,4.64 L17.5,14.36 C17.5,16.1 14.14,17.5 10,17.5 C5.86,17.5 2.5,16.09 2.5,14.36 L2.5,4.64"/></svg>',
"crosshairs": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="10" cy="10" r="7.5"/><line fill="none" stroke="#000" x1="10" x2="10" y2="8"/><line fill="none" stroke="#000" x1="10" y1="12" x2="10" y2="20"/><line fill="none" stroke="#000" y1="10" x2="8" y2="10"/><line fill="none" stroke="#000" x1="12" y1="10" x2="20" y2="10"/></svg>',
"credit-card": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="17" height="12" fill="none" stroke="#000" x="1.5" y="4.5"/><rect width="18" height="3" x="1" y="7"/></svg>',
"copy": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="12" height="16" fill="none" stroke="#000" x="3.5" y="2.5"/><polyline fill="none" stroke="#000" points="5 0.5 17.5 0.5 17.5 17"/></svg>',
"comments": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" points="2 0.5 19.5 0.5 19.5 13"/><path d="M5,19.71 L5,15 L0,15 L0,2 L18,2 L18,15 L9.71,15 L5,19.71 L5,19.71 L5,19.71 Z M1,14 L6,14 L6,17.29 L9.29,14 L17,14 L17,3 L1,3 L1,14 L1,14 L1,14 Z"/></svg>',
"commenting": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="1.5,1.5 18.5,1.5 18.5,13.5 10.5,13.5 6.5,17.5 6.5,13.5 1.5,13.5"/><circle cx="10" cy="8" r="1"/><circle cx="6" cy="8" r="1"/><circle cx="14" cy="8" r="1"/></svg>',
"comment": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M6,18.71 L6,14 L1,14 L1,1 L19,1 L19,14 L10.71,14 L6,18.71 L6,18.71 Z M2,13 L7,13 L7,16.29 L10.29,13 L18,13 L18,2 L2,2 L2,13 L2,13 Z"/></svg>',
"cog": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" cx="9.997" cy="10" r="3.31"/><path fill="none" stroke="#000" d="M18.488,12.285 L16.205,16.237 C15.322,15.496 14.185,15.281 13.303,15.791 C12.428,16.289 12.047,17.373 12.246,18.5 L7.735,18.5 C7.938,17.374 7.553,16.299 6.684,15.791 C5.801,15.27 4.655,15.492 3.773,16.237 L1.5,12.285 C2.573,11.871 3.317,10.999 3.317,9.991 C3.305,8.98 2.573,8.121 1.5,7.716 L3.765,3.784 C4.645,4.516 5.794,4.738 6.687,4.232 C7.555,3.722 7.939,2.637 7.735,1.5 L12.263,1.5 C12.072,2.637 12.441,3.71 13.314,4.22 C14.206,4.73 15.343,4.516 16.225,3.794 L18.487,7.714 C17.404,8.117 16.661,8.988 16.67,10.009 C16.672,11.018 17.415,11.88 18.488,12.285 L18.488,12.285 Z"/></svg>',
"code": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.01" points="13,4 19,10 13,16"/><polyline fill="none" stroke="#000" stroke-width="1.01" points="7,4 1,10 7,16"/></svg>',
"cloud-upload": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M6.5,13.77h-2.75c-1.79,0-3.25-1.44-3.25-3.22,0-1.63,1.22-2.98,2.81-3.19.07-2.89,2.44-5.2,5.37-5.2,2.51,0,4.63,1.71,5.21,4.02.5-.22,1.04-.34,1.61-.34,2.21,0,4,1.77,4,3.96s-1.79,3.96-4,3.96h-3"/><path fill="none" stroke="#000" d="M9.51,9.34v9"/><polyline fill="none" stroke="#000" points="6.34 11.85 9.51 8.68 12.68 11.85"/></svg>',
"cloud-download": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M6.5,13.28h-2.75c-1.79,0-3.25-1.44-3.25-3.22,0-1.63,1.22-2.98,2.8-3.19.08-2.89,2.45-5.2,5.38-5.2,2.51,0,4.63,1.71,5.21,4.02.5-.22,1.04-.34,1.61-.34,2.21,0,4,1.77,4,3.96s-1.79,3.96-4,3.96h-3"/><path fill="none" stroke="#000" d="M9.5,18.17v-10"/><polyline fill="none" stroke="#000" points="12.67 15.66 9.5 18.83 6.33 15.66"/></svg>',
"close": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.06" d="M16,16 L4,4"/><path fill="none" stroke="#000" stroke-width="1.06" d="M16,4 L4,16"/></svg>',
"close-circle": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><line fill="none" stroke="#000" x1="13.18" y1="6.82" x2="6.82" y2="13.18"/><line fill="none" stroke="#000" x1="6.82" y1="6.82" x2="13.18" y2="13.18"/></svg>',
"clock": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><rect width="1" height="7" x="9" y="4"/><path fill="none" stroke="#000" stroke-width="1.1" d="M13.018,14.197 L9.445,10.625"/></svg>',
"chevron-up": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="4 13 10 7 16 13"/></svg>',
"chevron-right": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="7 4 13 10 7 16"/></svg>',
"chevron-left": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="13 16 7 10 13 4"/></svg>',
"chevron-down": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="16 7 10 13 4 7"/></svg>',
"chevron-double-right": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="10 6 14 10 10 14"/><polyline fill="none" stroke="#000" stroke-width="1.03" points="6 6 10 10 6 14"/></svg>',
"chevron-double-left": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.03" points="10 14 6 10 10 6"/><polyline fill="none" stroke="#000" stroke-width="1.03" points="14 14 10 10 14 6"/></svg>',
"check": '<svg width="20" height="20" viewBox="0 0 20 20"><polyline fill="none" stroke="#000" stroke-width="1.1" points="4,10 8,15 17,4"/></svg>',
"cart": '<svg width="20" height="20" viewBox="0 0 20 20"><circle cx="7.3" cy="17.3" r="1.4"/><circle cx="13.3" cy="17.3" r="1.4"/><polyline fill="none" stroke="#000" points="0 2 3.2 4 5.3 12.5 16 12.5 18 6.5 8 6.5"/></svg>',
"camera": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10.8" r="3.8"/><path fill="none" stroke="#000" d="M1,4.5 C0.7,4.5 0.5,4.7 0.5,5 L0.5,17 C0.5,17.3 0.7,17.5 1,17.5 L19,17.5 C19.3,17.5 19.5,17.3 19.5,17 L19.5,5 C19.5,4.7 19.3,4.5 19,4.5 L13.5,4.5 L13.5,2.9 C13.5,2.6 13.3,2.5 13,2.5 L7,2.5 C6.7,2.5 6.5,2.6 6.5,2.9 L6.5,4.5 L1,4.5 L1,4.5 Z"/></svg>',
"calendar": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M 2,3 2,17 18,17 18,3 2,3 Z M 17,16 3,16 3,8 17,8 17,16 Z M 17,7 3,7 3,4 17,4 17,7 Z"/><rect width="1" height="3" x="6" y="2"/><rect width="1" height="3" x="13" y="2"/></svg>',
"bookmark": '<svg width="20" height="20" viewBox="0 0 20 20"><polygon fill="none" stroke="#000" points="5.5 1.5 15.5 1.5 15.5 17.5 10.5 12.5 5.5 17.5"/></svg>',
"bolt": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M4.74,20 L7.73,12 L3,12 L15.43,1 L12.32,9 L17.02,9 L4.74,20 L4.74,20 L4.74,20 Z M9.18,11 L7.1,16.39 L14.47,10 L10.86,10 L12.99,4.67 L5.61,11 L9.18,11 L9.18,11 L9.18,11 Z"/></svg>',
"bold": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M5,15.3 C5.66,15.3 5.9,15 5.9,14.53 L5.9,5.5 C5.9,4.92 5.56,4.7 5,4.7 L5,4 L8.95,4 C12.6,4 13.7,5.37 13.7,6.9 C13.7,7.87 13.14,9.17 10.86,9.59 L10.86,9.7 C13.25,9.86 14.29,11.28 14.3,12.54 C14.3,14.47 12.94,16 9,16 L5,16 L5,15.3 Z M9,9.3 C11.19,9.3 11.8,8.5 11.85,7 C11.85,5.65 11.3,4.8 9,4.8 L7.67,4.8 L7.67,9.3 L9,9.3 Z M9.185,15.22 C11.97,15 12.39,14 12.4,12.58 C12.4,11.15 11.39,10 9,10 L7.67,10 L7.67,15 L9.18,15 Z"/></svg>',
"bluesky": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M9.993,9.149c-.772-1.495-2.865-4.288-4.813-5.662-1.866-1.317-2.58-1.09-3.043-.878-.54.246-.637,1.075-.637,1.563s.265,4.003.444,4.587c.579,1.939,2.628,2.595,4.519,2.382.096-.014.193-.029.294-.039-.096.014-.198.029-.294.039-2.768.41-5.233,1.418-2.001,5.011,3.55,3.675,4.866-.786,5.541-3.053.675,2.262,1.452,6.564,5.474,3.053,3.024-3.053.83-4.601-1.939-5.011-.096-.01-.198-.024-.294-.039.101.014.198.024.294.039,1.89.212,3.945-.444,4.519-2.382.174-.588.444-4.099.444-4.587s-.096-1.317-.637-1.563c-.468-.212-1.177-.439-3.043.878-1.963,1.379-4.056,4.167-4.827,5.662h0Z"/></svg>',
"bell": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" stroke-width="1.1" d="M17,15.5 L3,15.5 C2.99,14.61 3.79,13.34 4.1,12.51 C4.58,11.3 4.72,10.35 5.19,7.01 C5.54,4.53 5.89,3.2 7.28,2.16 C8.13,1.56 9.37,1.5 9.81,1.5 L9.96,1.5 C9.96,1.5 11.62,1.41 12.67,2.17 C14.08,3.2 14.42,4.54 14.77,7.02 C15.26,10.35 15.4,11.31 15.87,12.52 C16.2,13.34 17.01,14.61 17,15.5 L17,15.5 Z"/><path fill="none" stroke="#000" d="M12.39,16 C12.39,17.37 11.35,18.43 9.91,18.43 C8.48,18.43 7.42,17.37 7.42,16"/></svg>',
"behance": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M9.5,10.6c-0.4-0.5-0.9-0.9-1.6-1.1c1.7-1,2.2-3.2,0.7-4.7C7.8,4,6.3,4,5.2,4C3.5,4,1.7,4,0,4v12c1.7,0,3.4,0,5.2,0 c1,0,2.1,0,3.1-0.5C10.2,14.6,10.5,12.3,9.5,10.6L9.5,10.6z M5.6,6.1c1.8,0,1.8,2.7-0.1,2.7c-1,0-2,0-2.9,0V6.1H5.6z M2.6,13.8v-3.1 c1.1,0,2.1,0,3.2,0c2.1,0,2.1,3.2,0.1,3.2L2.6,13.8z"/><path d="M19.9,10.9C19.7,9.2,18.7,7.6,17,7c-4.2-1.3-7.3,3.4-5.3,7.1c0.9,1.7,2.8,2.3,4.7,2.1c1.7-0.2,2.9-1.3,3.4-2.9h-2.2 c-0.4,1.3-2.4,1.5-3.5,0.6c-0.4-0.4-0.6-1.1-0.6-1.7H20C20,11.7,19.9,10.9,19.9,10.9z M13.5,10.6c0-1.6,2.3-2.7,3.5-1.4 c0.4,0.4,0.5,0.9,0.6,1.4H13.5L13.5,10.6z"/><rect width="5" height="1.4" x="13" y="4"/></svg>',
"ban": '<svg width="20" height="20" viewBox="0 0 20 20"><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"/><line fill="none" stroke="#000" stroke-width="1.1" x1="4" y1="3.5" x2="16" y2="16.5"/></svg>',
"bag": '<svg width="20" height="20" viewBox="0 0 20 20"><path fill="none" stroke="#000" d="M7.5,7.5V4A2.48,2.48,0,0,1,10,1.5,2.54,2.54,0,0,1,12.5,4V7.5"/><polygon fill="none" stroke="#000" points="16.5 7.5 3.5 7.5 2.5 18.5 17.5 18.5 16.5 7.5"/></svg>',
"arrow-up": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="16.53" x2="10" y2="4.53"/><polyline fill="none" stroke="#000" points="13.84 8 10 4.17 6.16 8"/></svg>',
"arrow-up-right": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="4.5" y1="15.53" x2="16.5" y2="3.53"/><polyline fill="none" stroke="#000" points="16.5 9 16.5 3.5 11 3.5"/></svg>',
"arrow-right": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="3.47" y1="10" x2="15.47" y2="10"/><polyline fill="none" stroke="#000" points="11.98 13.84 15.82 10 11.98 6.16"/></svg>',
"arrow-left": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="16.53" y1="10" x2="4.53" y2="10"/><polyline fill="none" stroke="#000" points="8 6.16 4.18 10 8 13.84"/></svg>',
"arrow-down": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="10" y1="3.48" x2="10" y2="15.48"/><polyline fill="none" stroke="#000" points="6.16 12 10 15.84 13.84 12"/></svg>',
"arrow-down-arrow-up": '<svg width="20" height="20" viewBox="0 0 20 20"><line fill="none" stroke="#000" x1="7" y1="3.38" x2="7" y2="15.38"/><polyline fill="none" stroke="#000" points="10.18 12.75 7 15.93 3.83 12.76"/><line fill="none" stroke="#000" x1="13" y1="16.62" x2="13" y2="4.62"/><polyline fill="none" stroke="#000" points="9.82 7.25 13 4.07 16.17 7.24"/></svg>',
"apple": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m17.23,6.93c-.1.08-1.95,1.12-1.95,3.43,0,2.67,2.35,3.62,2.42,3.64-.01.06-.37,1.29-1.24,2.55-.77,1.11-1.58,2.22-2.8,2.22s-1.54-.71-2.95-.71-1.87.73-2.99.73-1.9-1.03-2.8-2.29c-1.04-1.48-1.88-3.78-1.88-5.96,0-3.5,2.28-5.36,4.51-5.36,1.19,0,2.18.78,2.93.78s1.82-.83,3.17-.83c.51,0,2.36.05,3.57,1.79h0Zm-4.21-3.27c.56-.66.96-1.59.96-2.51,0-.13-.01-.26-.03-.36-.91.03-1.99.61-2.65,1.36-.51.58-.99,1.5-.99,2.44,0,.14.02.28.03.33.06.01.15.02.24.02.82,0,1.85-.55,2.44-1.28h0Z"/></svg>',
"android": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m14.88,6.77l1.66-2.87c.09-.16.04-.37-.12-.46-.16-.09-.37-.04-.46.12l-1.68,2.91c-1.28-.59-2.73-.91-4.28-.91s-3,.33-4.28.91l-1.68-2.91c-.09-.16-.3-.22-.46-.12-.16.09-.22.3-.12.46l1.66,2.87C2.26,8.32.32,11.22,0,14.61h20c-.32-3.39-2.26-6.29-5.12-7.84h0Zm-9.47,5.03c-.46,0-.84-.38-.84-.84s.38-.84.84-.84.84.38.84.84c0,.46-.37.84-.84.84Zm9.18,0c-.46,0-.84-.38-.84-.84s.38-.84.84-.84.84.38.84.84c0,.46-.37.84-.84.84Z"/></svg>',
"android-robot": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="m17.61,7.96v4.64c-.06,1.48-2.17,1.48-2.23,0v-4.64c.06-1.48,2.17-1.48,2.23,0Z"/><path d="m4.62,7.96v4.64c-.06,1.48-2.17,1.48-2.23,0v-4.64c.06-1.48,2.17-1.48,2.23,0Z"/><path d="m12.78,2.85c-.11-.07-.23-.13-.34-.19.13-.23.65-1.17.79-1.42.07-.12-.05-.27-.18-.23-.04.01-.07.04-.09.08l-.79,1.43c-1.32-.6-2.98-.6-4.3,0-.13-.23-.65-1.18-.79-1.43-.04-.07-.14-.1-.21-.06-.08.04-.1.14-.06.21,0,0,.79,1.42.79,1.42-1.49.77-2.53,2.28-2.53,3.99-.02,0,9.93,0,9.93,0,.01-1.55-.87-2.98-2.19-3.8Zm-5.07,1.98c-.23,0-.41-.19-.41-.41.01-.27.21-.41.41-.41s.4.14.42.41c0,.22-.18.42-.41.41Zm4.58,0c-.23,0-.42-.19-.41-.41.01-.28.21-.41.41-.41s.4.14.41.41c0,.23-.19.41-.41.41Z"/><path d="m14.97,7.03v7.2c0,.66-.54,1.2-1.2,1.2h-.8v2.46c-.06,1.48-2.16,1.48-2.23,0,0,0,0-2.46,0-2.46h-1.48v2.46c0,.61-.5,1.11-1.11,1.11s-1.11-.5-1.11-1.11v-2.46h-.8c-.66,0-1.2-.54-1.2-1.2,0,0,0-7.2,0-7.2h9.93Z"/></svg>',
"album": '<svg width="20" height="20" viewBox="0 0 20 20"><rect width="10" height="1" x="5" y="2"/><rect width="14" height="1" x="3" y="4"/><rect width="17" height="11" fill="none" stroke="#000" x="1.5" y="6.5"/></svg>',
"500px": '<svg width="20" height="20" viewBox="0 0 20 20"><path d="M9.624,11.866c-0.141,0.132,0.479,0.658,0.662,0.418c0.051-0.046,0.607-0.61,0.662-0.664c0,0,0.738,0.719,0.814,0.719 c0.1,0,0.207-0.055,0.322-0.17c0.27-0.269,0.135-0.416,0.066-0.495l-0.631-0.616l0.658-0.668c0.146-0.156,0.021-0.314-0.1-0.449 c-0.182-0.18-0.359-0.226-0.471-0.125l-0.656,0.654l-0.654-0.654c-0.033-0.034-0.08-0.045-0.124-0.045 c-0.079,0-0.191,0.068-0.307,0.181c-0.202,0.202-0.247,0.351-0.133,0.462l0.665,0.665L9.624,11.866z"/><path d="M11.066,2.884c-1.061,0-2.185,0.248-3.011,0.604c-0.087,0.034-0.141,0.106-0.15,0.205C7.893,3.784,7.919,3.909,7.982,4.066 c0.05,0.136,0.187,0.474,0.452,0.372c0.844-0.326,1.779-0.507,2.633-0.507c0.963,0,1.9,0.191,2.781,0.564 c0.695,0.292,1.357,0.719,2.078,1.34c0.051,0.044,0.105,0.068,0.164,0.068c0.143,0,0.273-0.137,0.389-0.271 c0.191-0.214,0.324-0.395,0.135-0.575c-0.686-0.654-1.436-1.138-2.363-1.533C13.24,3.097,12.168,2.884,11.066,2.884z"/><path d="M16.43,15.747c-0.092-0.028-0.242,0.05-0.309,0.119l0,0c-0.652,0.652-1.42,1.169-2.268,1.521 c-0.877,0.371-1.814,0.551-2.779,0.551c-0.961,0-1.896-0.189-2.775-0.564c-0.848-0.36-1.612-0.879-2.268-1.53 c-0.682-0.688-1.196-1.455-1.529-2.268c-0.325-0.799-0.471-1.643-0.471-1.643c-0.045-0.24-0.258-0.249-0.567-0.203 c-0.128,0.021-0.519,0.079-0.483,0.36v0.01c0.105,0.644,0.289,1.284,0.545,1.895c0.417,0.969,1.002,1.849,1.756,2.604 c0.757,0.754,1.636,1.34,2.604,1.757C8.901,18.785,9.97,19,11.088,19c1.104,0,2.186-0.215,3.188-0.645 c1.838-0.896,2.604-1.757,2.604-1.757c0.182-0.204,0.227-0.317-0.1-0.643C16.779,15.956,16.525,15.774,16.43,15.747z"/><path d="M5.633,13.287c0.293,0.71,0.723,1.341,1.262,1.882c0.54,0.54,1.172,0.971,1.882,1.264c0.731,0.303,1.509,0.461,2.298,0.461 c0.801,0,1.578-0.158,2.297-0.461c0.711-0.293,1.344-0.724,1.883-1.264c0.543-0.541,0.971-1.172,1.264-1.882 c0.314-0.721,0.463-1.5,0.463-2.298c0-0.79-0.148-1.569-0.463-2.289c-0.293-0.699-0.721-1.329-1.264-1.881 c-0.539-0.541-1.172-0.959-1.867-1.263c-0.721-0.303-1.5-0.461-2.299-0.461c-0.802,0-1.613,0.159-2.322,0.461 c-0.577,0.25-1.544,0.867-2.119,1.454v0.012V2.108h8.16C15.1,2.104,15.1,1.69,15.1,1.552C15.1,1.417,15.1,1,14.809,1H5.915 C5.676,1,5.527,1.192,5.527,1.384v6.84c0,0.214,0.273,0.372,0.529,0.428c0.5,0.105,0.614-0.056,0.737-0.224l0,0 c0.18-0.273,0.776-0.884,0.787-0.894c0.901-0.905,2.117-1.408,3.416-1.408c1.285,0,2.5,0.501,3.412,1.408 c0.914,0.914,1.408,2.122,1.408,3.405c0,1.288-0.508,2.496-1.408,3.405c-0.9,0.896-2.152,1.406-3.438,1.406 c-0.877,0-1.711-0.229-2.433-0.671v-4.158c0-0.553,0.237-1.151,0.643-1.614c0.462-0.519,1.094-0.799,1.782-0.799 c0.664,0,1.293,0.253,1.758,0.715c0.459,0.459,0.709,1.071,0.709,1.723c0,1.385-1.094,2.468-2.488,2.468 c-0.273,0-0.769-0.121-0.781-0.125c-0.281-0.087-0.405,0.306-0.438,0.436c-0.159,0.496,0.079,0.585,0.123,0.607 c0.452,0.137,0.743,0.157,1.129,0.157c1.973,0,3.572-1.6,3.572-3.57c0-1.964-1.6-3.552-3.572-3.552c-0.97,0-1.872,0.36-2.546,1.038 c-0.656,0.631-1.027,1.487-1.027,2.322v3.438v-0.011c-0.372-0.42-0.732-1.041-0.981-1.682c-0.102-0.248-0.315-0.202-0.607-0.113 c-0.135,0.035-0.519,0.157-0.44,0.439C5.372,12.799,5.577,13.164,5.633,13.287z"/></svg>'
});
}
if (typeof window !== "undefined" && window.UIkit) {
window.UIkit.use(plugin);
}
return plugin;
}));

1
static/js/uikit-icons.min.js vendored Normal file

File diff suppressed because one or more lines are too long

9925
static/js/uikit.js Normal file

File diff suppressed because it is too large Load Diff

1
static/js/uikit.min.js vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

5
stream.json Normal file
View File

@ -0,0 +1,5 @@
{
"last_known_title": "Maps!",
"viewer_count": -77,
"online": false
}

106
templates/events.html Normal file
View File

@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html" prefix="og: http://ogp.me/ns#">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title">Events</title>
<meta property="og:title" content="Treehouse Events">
<meta property="og:description" content="A Bulletin of all our events made using events.treehousefullofstars.com">
<meta property="og:site_name" content="Treehouse Events">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/stream.css') }}"/>
<link id="dark-mode" rel="stylesheet" href="{{ url_for('static', filename='css/dark-mode.css') }}" disabled/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<div uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky;">
<nav id="navbar" class="uk-navbar-container">
<div class="uk-container uk-container-expand">
<div uk-navbar="dropbar: true">
<div class="uk-navbar-left">
<p style="margin-top: 20px;"><strong>Events</strong></p>
</div>
<div class="uk-navbar-right uk-margin-small">
<div>
<a onclick="toggleDarkMode()" class="uk-button uk-button-small"><span id="modeToggle" class="uk-flex material-symbols-outlined">dark_mode</span></a>
</div>
<a href="#" class="uk-button uk-button-small" uk-icon="icon: menu" uk-toggle> Menu</a>
<div uk-dropdown="pos: bottom-right">
<ul class="uk-nav uk-dropdown-nav">
<li><a href="/">Home</a></li>
<li><a href="/stream">Stream</a></li>
<li><a href="/events">Events</a></li>
<li><a href="/radios">Radio</a></li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</div>
<div class="uk-container uk-section">
<div uk-grid>
<div class="uk-width-1-1">
<a href="https:/events.treehousefullofstars.com/new" target="_blank" class="uk-button uk-button-primary">Add Event</a>
</div>
<div class="uk-width-1-1">
<table class="uk-table uk-striped">
<thead>
<tr>
<th>Event Name</th>
<th>Location</th>
<th>Starts</th>
<th>Ends</th>
<th>Host</th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td><a href="https://events.treehousefullofstars.com/{{event['id']}}" target="_blank">{{event['name']}}</a></td>
<td>{{event['location']}}</td>
<td>{{event['start']}}</td>
<td>{{event['end']}}</td>
<td>{{event['hostName']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
<script>
var mode = false
async function toggleDarkMode() {
let darkMode = document.getElementById("dark-mode");
darkMode.disabled = !darkMode.disabled;
mode = !mode;
if(mode){
document.getElementById('modeToggle').innerHTML = "light_mode"
document.getElementById('main_html').classList.add('uk-light')
} else {
document.getElementById('modeToggle').innerHTML = "dark_mode"
document.getElementById('main_html').classList.remove('uk-light')
}
}
</script>
</html>

200
templates/home.html Normal file
View File

@ -0,0 +1,200 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html" prefix="og: http://ogp.me/ns#">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title">Treehouse</title>
<meta property="og:title" content="Treehouse">
<meta property="og:description" content="A Place to see all thats going on in the Treehouse!">
<meta property="og:site_name" content="Treehouse - Welcome Home">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/stream.css') }}"/>
<link id="dark-mode" rel="stylesheet" href="{{ url_for('static', filename='css/dark-mode.css') }}" disabled/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<div uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky;">
<nav id="navbar" class="uk-navbar-container">
<div class="uk-container uk-container-expand">
<div uk-navbar="dropbar: true">
<div class="uk-navbar-left">
<p style="margin-top: 20px;"><strong>Home</strong></p>
</div>
<div class="uk-navbar-right uk-margin-small">
<div>
<a onclick="toggleDarkMode()" class="uk-button uk-button-small"><span id="modeToggle" class="uk-flex material-symbols-outlined">dark_mode</span></a>
</div>
<a href="#" class="uk-button uk-button-small" uk-icon="icon: menu" uk-toggle> Menu</a>
<div uk-dropdown="pos: bottom-right">
<ul class="uk-nav uk-dropdown-nav">
<li><a href="/">Home</a></li>
<li><a href="/stream">Stream</a></li>
<li><a href="/events">Events</a></li>
<li><a href="/radios">Radio</a></li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</div>
<div class="uk-container uk-section">
<div uk-grid>
<div class="uk-width-1-2@m uk-grid-small" uk-grid>
<div class="uk-width-1-1">
<button onclick="refreshNotes()" class="uk-button uk-button-default"><span uk-icon="icon: refresh"></span></button>
<a href="https://misskey.treehousefullofstars.com" target="_blank" class="uk-button uk-button-default">Misskey <span uk-icon="icon: link-external"></span></a>
</div>
<div style="height:80vh; overflow-y: auto;" id="notesView"></div>
</div>
<div class="uk-width-1-2@m">
<div style="padding: 5px; border-radius: 10px;" class="uk-text-center StreamStatus">
<h3>{{stream['last_known_title']}} <a href="/stream" uk-icon="icon: link" target="_blank"></a>
{% if stream['online'] %}
<span style="margin-left: 20px;" class="uk-label uk-label-success">Online</span>
{% else %}
<span class="uk-label uk-label-danger">Offline</span>
{% endif %}
</h3>
<p style="position: relative; margin-top: 0px;">{{stream['viewer_count']}} Viewers</p>
</div>
<div>
{% for radio in radios %}
<div style="padding: 10px; border: 10px;" class="uk-width-1-1">
<h5>{{radio['name']}} <a href="{{radio['public_player_url']}}" target="_blank" class="uk-button uk-button-small">Open Public Page</a></h5>
<iframe src="{{radio['public_player_url']}}/embed?theme=light" style="width: 100%; min-height: 150px; border: 0;"></iframe>
</div>
{% endfor %}
</div>
<div>
<caption>Upcoming Events</caption>
<table class="uk-table uk-table-striped">
<thead>
<tr>
<th>Event Name</th>
<th>Location</th>
<th>Starts</th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td><a href="https://events.treehousefullofstars.com/{{event['id']}}" target="_blank">{{event['name']}}</a></td>
<td>{{event['location']}}</td>
<td>{{event['start']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
<script>
// function sendNotification(title, message) {
// window.electronAPI.sendNotification(title, message)
//}
// Example usage
//document.addEventListener('DOMContentLoaded', () => {
// sendNotification('loaded', 'Hello from Renderer Process!');
//});
document.addEventListener('DOMContentLoaded', async function() {
let notes = await fetchNotes()
await rebuildNotesView(notes)
});
async function fetchNotes(){
const url = new URL('/getNotes', window.location.origin)
const response = await fetch(url)
data = await response.json()
return data.notes
}
async function rebuildNotesView(notes){
let notesView = document.getElementById('notesView')
notesView.innerHTML = ""
for(i=0; i < notes.length; i++){
console.log(notes[i])
let article = document.createElement('article')
article.role = "comment"
article.setAttribute('class', 'uk-comment uk-comment-primary')
let header = document.createElement('header')
header.setAttribute('class', 'uk-comment-header')
let grid = document.createElement('div')
grid.setAttribute('class', 'uk-grid uk-grid-medium uk-flex-middle')
let comment_image = document.createElement('div')
comment_image.setAttribute('class', 'uk-width-auto')
comment_image.innerHTML = `<img class="uk-comment-avatar uk-border-circle" src="${notes[i].user.avatarUrl}" width="80" height="80" alt="">`
let comment_header= document.createElement('div')
comment_header.setAttribute('class', 'uk-width-expand')
comment_header.innerHTML = `
<h4 class="uk-comment-title uk-margin-remove"><a class="uk-link-reset" href="#">${notes[i].user.name}</a></h4>
<ul class="uk-comment-meta uk-subnav uk-subnav-divider uk-margin-remove-top">
<li><a href="#">${notes[i].createdAt}</a></li>
<li><a href="#">link</a></li>
</ul>`
grid.append(comment_image, comment_header)
header.append(grid)
article.append(header)
let comment_body = document.createElement('div')
comment_body.setAttribute('class', 'uk-comment-body')
comment_body.innerHTML = `<p>${notes[i].text}</p>`
article.append(comment_body)
notesView.append(article)
}
}
async function refreshNotes(){
let notes = await fetchNotes()
await rebuildNotesView(notes)
}
var mode = false
async function toggleDarkMode() {
let darkMode = document.getElementById("dark-mode");
darkMode.disabled = !darkMode.disabled;
mode = !mode;
if(mode){
document.getElementById('modeToggle').innerHTML = "light_mode"
document.getElementById('main_html').classList.add('uk-light')
} else {
document.getElementById('modeToggle').innerHTML = "dark_mode"
document.getElementById('main_html').classList.remove('uk-light')
}
sendNotification('Dark Mode', 'Tis has been activated mi lady!')
}
</script>
</html>

86
templates/radios.html Normal file
View File

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html" prefix="og: http://ogp.me/ns#">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title">Radios</title>
<meta property="og:title" content="Treehouse Radio">
<meta property="og:description" content="A Series of music rooms to listen and enjoy music together!">
<meta property="og:site_name" content="Treehouse Radio">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/stream.css') }}"/>
<link id="dark-mode" rel="stylesheet" href="{{ url_for('static', filename='css/dark-mode.css') }}" disabled/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<div uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky;">
<nav id="navbar" class="uk-navbar-container">
<div class="uk-container uk-container-expand">
<div uk-navbar="dropbar: true">
<div class="uk-navbar-left">
<p style="margin-top: 20px;"><strong>Radios</strong></p>
</div>
<div class="uk-navbar-right uk-margin-small">
<div>
<a onclick="toggleDarkMode()" class="uk-button uk-button-small"><span id="modeToggle" class="uk-flex material-symbols-outlined">dark_mode</span></a>
</div>
<a href="#" class="uk-button uk-button-small" uk-icon="icon: menu" uk-toggle> Menu</a>
<div uk-dropdown="pos: bottom-right">
<ul class="uk-nav uk-dropdown-nav">
<li><a href="/">Home</a></li>
<li><a href="/stream">Stream</a></li>
<li><a href="/events">Events</a></li>
<li><a href="/radios">Radio</a></li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</div>
<div class="uk-container uk-section">
<div class="uk-grid-small" uk-grid>
{% for radio in radios %}
<div style="padding: 10px; border: 10px;" class="uk-width-1-1">
<h5>{{radio['name']}} <a href="{{radio['public_player_url']}}" target="_blank" class="uk-button uk-button-small">Open Public Page</a></h5>
<iframe src="{{radio['public_player_url']}}/embed?theme=light" style="width: 100%; min-height: 150px; border: 0;"></iframe>
</div>
{% endfor %}
</div>
</div>
</body>
<script>
var mode = false
async function toggleDarkMode() {
let darkMode = document.getElementById("dark-mode");
darkMode.disabled = !darkMode.disabled;
mode = !mode;
if(mode){
document.getElementById('modeToggle').innerHTML = "light_mode"
document.getElementById('main_html').classList.add('uk-light')
} else {
document.getElementById('modeToggle').innerHTML = "dark_mode"
document.getElementById('main_html').classList.remove('uk-light')
}
}
</script>
</html>

342
templates/stream.html Normal file
View File

@ -0,0 +1,342 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" id="main_html" prefix="og: http://ogp.me/ns#">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
<title id="title">{{metadata['last_known_title']}}</title>
<meta property="og:title" content="{{metadata['last_known_title']}}">
<meta property="og:description" content="A place where we get together a stream while hanging out!">
<meta property="og:image" content="{{url_for('static', filename='website_images/poster.jpg')}}">
<meta property="og:url" content="http://184.83.153.182:5000/stream">
<meta property="og:type" content="video"> <!-- Can be 'article', 'video', etc. -->
<meta property="og:site_name" content="Treehouse Theatre">
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<!-- Material Symbols - Outlined Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<!-- Material Symbols - Rounded Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
<!-- Material Symbols - Sharp Set -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static', filename='css/stream.css') }}"/>
<link id="dark-mode" rel="stylesheet" href="{{ url_for('static', filename='css/dark-mode.css') }}" disabled/>
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<div uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky;">
<nav id="navbar" class="uk-navbar-container">
<div class="uk-container uk-container-expand">
<div uk-navbar="dropbar: true">
<div class="uk-navbar-left">
<p style="margin-top: 20px;"><strong>{{metadata['last_known_title']}}</strong></p>
</div>
<div class="uk-navbar-right uk-margin-small">
<div>
<a onclick="toggleDarkMode()" class="uk-button uk-button-small"><span id="modeToggle" class="uk-flex material-symbols-outlined">dark_mode</span></a>
</div>
<a href="#" class="uk-button uk-button-small" uk-icon="icon: menu" uk-toggle> Menu</a>
<div uk-dropdown="pos: bottom-right">
<ul class="uk-nav uk-dropdown-nav">
<li><a href="/">Home</a></li>
<li><a href="/stream">Stream</a></li>
<li><a href="/events">Events</a></li>
<li><a href="/radios">Radio</a></li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</div>
<div style="margin-top: 30px;">
<div class="uk-container uk-container-xlarge">
<div class="testContainer">
<div id="video-container" class="video-container">
<div class="blurred-background"></div>
<video id="videoPlayer" class="uk-video" autoplay playsinline controls poster="{{ url_for('static', filename='website_images/poster.jpg') }}">Your browser does not support the video tag.</video>
</div>
<div id="chat-container" class="chat-container" hidden>
<div id="chat">
</div>
<div id="test" class="floating-square">
<div class="input-container">
<textarea id="messageInput" class="full-width-input" placeholder="Type your thoughts..." maxlength="255"></textarea>
</div>
<button id="sendButton" onclick="sendMessage()" class="send-button"><span class="material-symbols-outlined">
send
</span></button>
</div>
</div>
</div>
<div class="dock" uk-grid>
<div style="padding: 5px" class="uk-width-1-2">
<p id="viewer-count" class="uk-text-meta">{{metadata['viewer_count']+1}} Viewers</p>
</div>
<div style="padding: 5px" class="uk-width-1-2">
<button style="border-radius: 20px;" class="uk-button uk-button-small uk-align-right mybutton" id="popout-button" hidden>Chat</button>
<button onclick="toggleViewMode()" style="border-radius: 20px;" class="uk-button uk-button-small uk-align-right" id="view_mode" hidden>
Theatre
</button>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
<script>
url = `${location.origin}`
console.log(url)
var socket = io.connect(url);
var thishost = location.hostname
var username;
document.addEventListener('DOMContentLoaded', function() {
const videoContainer = document.getElementById('video-container');
const scrollableDiv = document.getElementById('chat-container');
function setScrollableDivHeight() {
scrollableDiv.style.height = `${videoContainer.clientHeight}px`;
}
// Set the initial height
setScrollableDivHeight();
// Update the height on window resize
window.addEventListener('resize', setScrollableDivHeight);
});
socket.on('titleChanged', function(data) {
document.getElementById('streamTitle').innerHTML = `<strong>${data}</strong>`
});
socket.on('updateViewerCount', function(data) {
document.getElementById('viewer-count').innerHTML = `${data} Viewers`
});
socket.on('userJoined', function(data) {
console.log(`JOIN: ${JSON.stringify(data)}`)
UIkit.notification({
message: `${data.user.displayName} has joined the chat!`,
status: 'secondary',
pos: 'bottom-center',
timeout: 5000
});
});
socket.on('userLeft', function(data) {
console.log(`LEFT: ${JSON.stringify(data)}`)
UIkit.notification({
message: `${data.user.displayName} has left the chat!`,
status: 'secondary',
pos: 'bottom-center',
timeout: 5000
});
});
socket.on('userNameChanged', function(data) {
console.log(`NAME_CHANGE: ${JSON.stringify(data)}`)
UIkit.notification({
message: `${data.user.previousNames.at(-1)} changed their name to ${data.newName}`,
status: 'secondary',
pos: 'bottom-center',
timeout: 5000
});
});
socket.on('newMessage', function() {
UIkit.notification({
message: `Chat has a new message!`,
status: 'secondary',
pos: 'bottom-center',
timeout: 5000
});
});
socket.on('joined', function(data) {
username = data.username
});
function sendMessage(){
let message = document.getElementById('messageInput')
let currentTime = new Date();
let timeString = currentTime.toLocaleTimeString();
let dateString = currentTime.toLocaleDateString();
let dateTimeString = `${dateString} ${timeString}`;
socket.emit('messageSend', {'message_content': message.value, 'channel_id': "stream", 'username': username, 'timestamp': currentTime})
message.value = '';
}
socket.on('messageReceive', function(data) {
console.log(data)
let message = data;
// instead of adding the message do I just reload the messages? what kind of infranstructure would that require.
addMessage(data)
});
async function joinStream(){
socket.emit('join');
}
joinStream()
document.getElementById('popout-button').addEventListener('click', function() {
// Define the URL of the Owncast chat
const chatUrl = `http://${thishost}:8086/embed/chat/readwrite`;
// Define the dimensions of the new window
const width = 600;
const height = 400;
// Calculate the position of the new window
const left = (window.screen.width - width) / 2;
const top = (window.screen.height - height) / 2;
// Open the chat in a new window
window.open(chatUrl, 'OwncastChat', `width=${width},height=${height},left=${left},top=${top}`);
});
// Get the video element
const video = document.getElementById('videoPlayer');
// Check if the browser supports HLS natively
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(`http://${thishost}:8086/hls/stream.m3u8`);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// If the browser natively supports HLS
console.log('maybe')
video.src = `http://${thishost}:8086/hls/stream.m3u8`;
} else {
// Fallback message for unsupported browsers
video.poster="fallback-image.jpg";
video.innerHTML = 'Your browser does not support HLS. Please use a modern browser.';
}
const mainVideo = document.getElementById('videoPlayer');
const blurredBackground = document.querySelector('.blurred-background');
// Create a canvas to draw the video frame
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set the canvas size to match the video
mainVideo.addEventListener('loadedmetadata', () => {
canvas.width = mainVideo.videoWidth;
canvas.height = mainVideo.videoHeight;
});
// Function to update the blurred background
function updateBlurredBackground() {
if (mainVideo.readyState === mainVideo.HAVE_ENOUGH_DATA) {
// Draw the current video frame onto the canvas
ctx.drawImage(mainVideo, 0, 0, canvas.width, canvas.height);
// Convert the canvas content to a Data URL
const dataUrl = canvas.toDataURL();
// Set the Data URL as the background image of the blurred background
blurredBackground.style.backgroundImage = `url(${dataUrl})`;
}
// Request the next frame update
requestAnimationFrame(updateBlurredBackground);
}
// Start updating the blurred background when the video plays
var background_blur = false
//mainVideo.addEventListener('play', () => {
// blurrBackground()
//});
function blurrBackground(){
if(background_blur){
updateBlurredBackground();
}
}
async function addMessage(data){
let message_card = document.createElement('div')
message_card.setAttribute('class', 'message-card')
let user_info = document.createElement('div')
user_info.setAttribute('class', 'user-info')
let image = document.createElement('img')
image.setAttribute('class', 'avatar')
image.setAttribute('src', "static/website_images/placeholder.webp")
let username = document.createElement('span')
username.setAttribute('class', 'username')
username.innerHTML = data.username
let timestamp = document.createElement('span')
timestamp.setAttribute('class', 'timestamp')
timestamp.innerHTML = data.timestamp
user_info.append(image)
user_info.append(username)
message_card.append(user_info)
message_card.append(timestamp)
let message = document.createElement('div')
message.setAttribute('class', 'message-content')
test = `${data.message_content}`
message.innerHTML = `${test}`
console.log(message.innerHTML.length)
message_card.append(message)
document.getElementById('chat').append(message_card)
document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight;
}
var mode = false
async function toggleDarkMode() {
let darkMode = document.getElementById("dark-mode");
darkMode.disabled = !darkMode.disabled;
mode = !mode;
if(mode){
document.getElementById('modeToggle').innerHTML = "light_mode"
document.getElementById('main_html').classList.add('uk-light')
} else {
document.getElementById('modeToggle').innerHTML = "dark_mode"
document.getElementById('main_html').classList.remove('uk-light')
}
}
var detail_mode = true
async function toggleViewMode(){
detail_mode = !detail_mode
if (detail_mode){
console.log('Detail Mode Activate')
document.getElementById('popout-button').hidden = false
document.getElementById('viewer-count').hidden = false
background_blur = false
blurredBackground.style.backgroundImage = `none`;
} else {
console.log('Detail Mode Deactivate')
document.getElementById('popout-button').hidden = true
document.getElementById('viewer-count').hidden = true
background_blur = true
blurrBackground()
}
}
</script>
</html>

45
test.json Normal file
View File

@ -0,0 +1,45 @@
{
"type": "channel",
"body": {
"id": "a79jhleyz47f00j9",
"type": "note",
"body": {
"id": "a855mm45csjw00m7",
"createdAt": "2025-05-24T02:08:03.701Z",
"userId": "a79jhleyz47f00j9",
"user": {
"id": "a79jhleyz47f00j9",
"name": "Sherpa",
"username": "sherpa",
"host": null,
"avatarUrl": "https://misskey.treehousefullofstars.com/proxy/avatar.webp?url=https%3A%2F%2Fmisskey.treehousefullofstars.com%2Ffiles%2Fwebpublic-6310af6e-e633-4a6e-899c-1c69eea61629&avatar=1",
"avatarBlurhash": "e9H2G[000cq_~q_2M{Ios;^*00pIso-;EhxrnOf59bOYY6Vr={D*t8",
"avatarDecorations": [],
"isBot": true,
"isCat": false,
"emojis": {},
"onlineStatus": "offline",
"badgeRoles": []
},
"text": "**Treehouse Full of Stars**\n'Maps!' has finished! I hope you enjoyed and stick around to chat! #stream",
"cw": null,
"visibility": "public",
"localOnly": false,
"reactionAcceptance": null,
"renoteCount": 0,
"repliesCount": 0,
"reactionCount": 0,
"reactions": {},
"reactionEmojis": {},
"reactionAndUserPairCache": [],
"tags": [
"stream"
],
"fileIds": [],
"files": [],
"replyId": null,
"renoteId": null,
"clippedCount": 0
}
}
}

20
test.py Normal file
View File

@ -0,0 +1,20 @@
import requests
import json
bot_token = "MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI"
guild_id = "954201387770736751"
discord_id = "189202462442389514"
headers = {'Authorization': f'Bot {bot_token}'}
discord_guild_endpoint = f"https://discord.com/api/v10/guilds/{guild_id}/members/{discord_id}"
response = requests.get(discord_guild_endpoint, headers=headers)
print(response.status_code)
if response.status_code == 200:
discord_user = response.json()
with open('test2.json', 'w+') as file:
file.write(json.dumps(discord_user, indent=5))
avatar_decor_endpoint = "https://cdn.discordapp.com/" + f"avatar-decoration-presets/{discord_user["user"]["avatar_decoration_data"]["asset"]}.png"
response = requests.get(avatar_decor_endpoint, headers=headers)
with open("avatar_decoration.png", "wb") as f:
f.write(response.content)

48
test2.json Normal file
View File

@ -0,0 +1,48 @@
{
"avatar": "f9ce75ba5e0d40ac6d1992cf814b11a5",
"avatar_decoration_data": {
"asset": "a_aa2e1c2b3cf05b24f6ec7b8b4141f5fc",
"sku_id": "1144056631374647458",
"expires_at": null
},
"banner": "3786a1a06734f5c25452774e33418a20",
"communication_disabled_until": null,
"flags": 0,
"joined_at": "2022-04-10T03:34:32.149000+00:00",
"nick": "Ro",
"pending": false,
"premium_since": "2023-07-17T02:50:10.626000+00:00",
"roles": [
"1176709173740834888",
"1182553718042918952",
"1156406147822133258",
"1130330579741704203",
"1185711553606074408",
"1154611585965371453",
"1127803161353125908",
"1185079212223250493"
],
"unusual_dm_activity_until": null,
"user": {
"id": "189202462442389514",
"username": "andhrimnir",
"avatar": "a_3a2ba0b099cc29e88deb6831f8a72731",
"discriminator": "0",
"public_flags": 0,
"flags": 0,
"banner": "a_08fe1aae1a557f1cce675b9cbfacdbf7",
"accent_color": 6691868,
"global_name": "Rowan Peregrine-Versi",
"avatar_decoration_data": {
"asset": "a_aa2e1c2b3cf05b24f6ec7b8b4141f5fc",
"sku_id": "1144056631374647458",
"expires_at": null
},
"collectibles": null,
"banner_color": "#661c1c",
"clan": null,
"primary_guild": null
},
"mute": false,
"deaf": false
}

120
user copy.json Normal file
View File

@ -0,0 +1,120 @@
{
"user": {
"id": "a78vufh1z47f000t",
"name": "Gabriella Versi",
"username": "gabriella",
"host": null,
"avatarUrl": "https://misskey.treehousefullofstars.com/proxy/avatar.webp?url=https%3A%2F%2Fmisskey.treehousefullofstars.com%2Ffiles%2Ffd8eb725-2948-41ab-afeb-2fd5cac7290a&avatar=1",
"avatarBlurhash": "eJHL3x0g9w~UVs_NaKD%xtM{9Zt7VrR+tRx]s:RkofxtWBWBWAWqay",
"avatarDecorations": [],
"isBot": false,
"isCat": false,
"emojis": {},
"onlineStatus": "online",
"badgeRoles": [],
"url": null,
"uri": null,
"movedTo": null,
"alsoKnownAs": null,
"createdAt": "2025-05-01T12:05:34.549Z",
"updatedAt": "2025-05-04T02:33:04.236Z",
"lastFetchedAt": null,
"bannerUrl": "https://misskey.treehousefullofstars.com/files/126a481b-eb1d-46f1-a91f-7e78d5bf0bde",
"bannerBlurhash": "eFKdrFRi8^%M9a_4O@RNM{NGI--P%1RiIU9c$xE1kXRP9HnU%eWAM|",
"isLocked": false,
"isSilenced": false,
"isSuspended": false,
"description": "As the mother of triplets, her life has changed drastically from what she once knew. Once a Pirate, then a Paladin, and now settled with a family, her whole past and future is wrapped up in the mystery of time. Also partially Augmented to keep herself alive!",
"location": "Eorzea",
"birthday": "1994-06-01",
"lang": "en-US",
"fields": [
{
"name": "Lore",
"value": "https://bookstack.treehousefullofstars.com/books/gabriella-versi"
},
{
"name": "Lodestone",
"value": "https://na.finalfantasyxiv.com/lodestone/character/36117492/"
},
{
"name": "Discord",
"value": "407247496008433675"
}
],
"verifiedLinks": [],
"followersCount": 5,
"followingCount": 5,
"notesCount": 68,
"pinnedNoteIds": [],
"pinnedNotes": [],
"pinnedPageId": null,
"pinnedPage": null,
"publicReactions": true,
"followersVisibility": "public",
"followingVisibility": "public",
"chatScope": "mutual",
"canChat": true,
"roles": [
{
"id": "a7b57qy6z47f014i",
"name": "Blossom",
"color": "#af68cf",
"iconUrl": null,
"description": "This is the basic user Role!",
"isModerator": false,
"isAdministrator": false,
"displayOrder": 0
}
],
"memo": null,
"isFollowing": true,
"isFollowed": true,
"hasPendingFollowRequestFromYou": false,
"hasPendingFollowRequestToYou": false,
"isBlocking": false,
"isBlocked": false,
"isMuted": false,
"isRenoteMuted": false,
"notify": "none",
"withReplies": false,
"followedMessage": "I hope your days are generous to you!"
},
"discord": {
"avatar": "1353ce88f8bc29d0ecaf6807cfd1c166",
"banner": "2ce690bee165ff6ff0950b34502e6bed",
"communication_disabled_until": null,
"flags": 0,
"joined_at": "2022-03-18T02:15:39.095000+00:00",
"nick": "Gabriella",
"pending": false,
"premium_since": "2023-07-17T02:51:51.835000+00:00",
"roles": [
"1176709173740834888",
"1182553718042918952",
"1130330579741704203",
"1185079212223250493"
],
"unusual_dm_activity_until": null,
"user": {
"id": "407247496008433675",
"username": "mechseroms",
"avatar": "8264db5f27003a0d68469a4586452dd2",
"discriminator": "0",
"public_flags": 0,
"flags": 0,
"banner": "bc8283925212ceeb26da8292856f2923",
"accent_color": null,
"global_name": "Mechseroms",
"avatar_decoration_data": null,
"collectibles": null,
"banner_color": null,
"clan": null,
"primary_guild": null
},
"mute": false,
"deaf": false
}
}
//{'type': 'channel', 'body': {'id': 'a79jhleyz47f00j9', 'type': 'note', 'body': {'id': 'a7clpqlhz47f01gc', 'createdAt': '2025-05-04T02:33:04.229Z', 'userId': 'a78vufh1z47f000t', 'user': {'id': 'a78vufh1z47f000t', 'name': 'Gabriella Versi', 'username': 'gabriella', 'host': None, 'avatarUrl': 'https://misskey.treehousefullofstars.com/proxy/avatar.webp?url=https%3A%2F%2Fmisskey.treehousefullofstars.com%2Ffiles%2Ffd8eb725-2948-41ab-afeb-2fd5cac7290a&avatar=1', 'avatarBlurhash': 'eJHL3x0g9w~UVs_NaKD%xtM{9Zt7VrR+tRx]s:RkofxtWBWBWAWqay', 'avatarDecorations': [], 'isBot': False, 'isCat': False, 'emojis': {}, 'onlineStatus': 'online', 'badgeRoles': []}, 'text': 'test @jadowyne', 'cw': None, 'visibility': 'public', 'localOnly': False, 'reactionAcceptance': None, 'renoteCount': 0, 'repliesCount': 0, 'reactionCount': 0, 'reactions': {}, 'reactionEmojis': {}, 'reactionAndUserPairCache': [], 'fileIds': [], 'files': [], 'replyId': None, 'renoteId': None, 'mentions': ['a78vb2l4z47f0003'], 'clippedCount': 0}}}

162
user.json Normal file
View File

@ -0,0 +1,162 @@
{
"user": {
"id": "a79jhleyz47f00j9",
"name": "Sherpa",
"username": "sherpa",
"host": null,
"avatarUrl": "https://misskey.treehousefullofstars.com/proxy/avatar.webp?url=https%3A%2F%2Fmisskey.treehousefullofstars.com%2Ffiles%2Fwebpublic-6310af6e-e633-4a6e-899c-1c69eea61629&avatar=1",
"avatarBlurhash": "e9H2G[000cq_~q_2M{Ios;^*00pIso-;EhxrnOf59bOYY6Vr={D*t8",
"avatarDecorations": [],
"isBot": true,
"isCat": false,
"emojis": {},
"onlineStatus": "offline",
"badgeRoles": [],
"url": null,
"uri": null,
"movedTo": null,
"alsoKnownAs": null,
"createdAt": "2025-05-01T23:07:26.506Z",
"updatedAt": "2025-05-24T02:08:03.707Z",
"lastFetchedAt": null,
"bannerUrl": null,
"bannerBlurhash": null,
"isLocked": false,
"isSilenced": false,
"isSuspended": false,
"description": "I am the Kindly Maid for the Treehouse Full of Stars.",
"location": null,
"birthday": null,
"lang": null,
"fields": [],
"verifiedLinks": [],
"followersCount": 4,
"followingCount": 3,
"notesCount": 67,
"pinnedNoteIds": [],
"pinnedNotes": [],
"pinnedPageId": null,
"pinnedPage": null,
"publicReactions": true,
"followersVisibility": "public",
"followingVisibility": "public",
"chatScope": "mutual",
"canChat": true,
"roles": [],
"memo": null,
"twoFactorEnabled": false,
"usePasswordLessLogin": false,
"securityKeys": false,
"avatarId": "a79k2n3bz47f00kf",
"bannerId": null,
"followedMessage": null,
"isModerator": false,
"isAdmin": false,
"injectFeaturedNote": true,
"receiveAnnouncementEmail": true,
"alwaysMarkNsfw": false,
"autoSensitive": false,
"carefulBot": false,
"autoAcceptFollowed": true,
"noCrawle": true,
"preventAiLearning": true,
"isExplorable": true,
"isDeleted": false,
"twoFactorBackupCodesStock": "none",
"hideOnlineStatus": false,
"hasUnreadSpecifiedNotes": false,
"hasUnreadMentions": false,
"hasUnreadChatMessages": false,
"hasUnreadAnnouncement": false,
"unreadAnnouncements": [],
"hasUnreadAntenna": false,
"hasUnreadChannel": false,
"hasUnreadNotification": true,
"hasPendingReceivedFollowRequest": false,
"unreadNotificationsCount": 9,
"mutedWords": [],
"hardMutedWords": [],
"mutedInstances": [],
"mutingNotificationTypes": [],
"notificationRecieveConfig": {},
"emailNotificationTypes": [
"follow",
"receiveFollowRequest"
],
"achievements": [
{
"name": "profileFilled",
"unlockedAt": 1746140882030
},
{
"name": "notes1",
"unlockedAt": 1746141667039
},
{
"name": "followers1",
"unlockedAt": 1746142890781
},
{
"name": "following1",
"unlockedAt": 1746156433107
},
{
"name": "noteDeletedWithin1min",
"unlockedAt": 1746186576029
},
{
"name": "login3",
"unlockedAt": 1746234162094
},
{
"name": "notes10",
"unlockedAt": 1746234162597
},
{
"name": "client30min",
"unlockedAt": 1746570124072
},
{
"name": "login7",
"unlockedAt": 1746649091904
}
],
"loggedInDays": 17,
"policies": {
"gtlAvailable": true,
"ltlAvailable": true,
"canPublicNote": true,
"mentionLimit": 20,
"canInvite": false,
"inviteLimit": 0,
"inviteLimitCycle": 10080,
"inviteExpirationTime": 0,
"canManageCustomEmojis": false,
"canManageAvatarDecorations": false,
"canSearchNotes": false,
"canUseTranslator": true,
"canHideAds": false,
"driveCapacityMb": 100,
"maxFileSizeMb": 10,
"alwaysMarkNsfw": false,
"canUpdateBioMedia": true,
"pinLimit": 5,
"antennaLimit": 5,
"wordMuteLimit": 200,
"webhookLimit": 3,
"clipLimit": 10,
"noteEachClipsLimit": 200,
"userListLimit": 10,
"userEachUserListsLimit": 50,
"rateLimitFactor": 1,
"avatarDecorationLimit": 1,
"canImportAntennas": true,
"canImportBlocking": true,
"canImportFollowing": true,
"canImportMuting": true,
"canImportUserLists": true,
"chatAvailability": "available"
}
},
"discord": {}
}