first commit
This commit is contained in:
commit
51f9c8f8fd
BIN
avatar_decoration.png
Normal file
BIN
avatar_decoration.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
91
discord_listener.py
Normal file
91
discord_listener.py
Normal 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
1
events.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
290
main.py
Normal file
290
main.py
Normal 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
189
misskey_bridge.py
Normal 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
55
static/css/dark-mode.css
Normal 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
208
static/css/stream.css
Normal 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
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
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
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
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
184
static/js/uikit-icons.js
Normal 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
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
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
1
static/js/uikit.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
static/website_images/placeholder.webp
Normal file
BIN
static/website_images/placeholder.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
static/website_images/poster.jpg
Normal file
BIN
static/website_images/poster.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 290 KiB |
BIN
static/website_images/poster.xcf
Normal file
BIN
static/website_images/poster.xcf
Normal file
Binary file not shown.
5
stream.json
Normal file
5
stream.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"last_known_title": "Maps!",
|
||||||
|
"viewer_count": -77,
|
||||||
|
"online": false
|
||||||
|
}
|
||||||
106
templates/events.html
Normal file
106
templates/events.html
Normal 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
200
templates/home.html
Normal 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
86
templates/radios.html
Normal 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
342
templates/stream.html
Normal 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
45
test.json
Normal 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
20
test.py
Normal 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
48
test2.json
Normal 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
120
user copy.json
Normal 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
162
user.json
Normal 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": {}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user