fsdfsd
This commit is contained in:
parent
5d258ae3a6
commit
00f138acc7
13 changed files with 34 additions and 34 deletions
|
@ -53,7 +53,7 @@ lite-youtube > .lty-playbtn {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
/* YT's actual play button svg */
|
/* YT's actual play button svg */
|
||||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="red"/><path d="M45 24 27 14v20" fill="white"/></svg>');
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="red"/><path d="M45 24 27 14v20" fill="white"/></svg>');
|
||||||
filter: grayscale(100%);
|
filter: grayscale(100%);
|
||||||
transition: filter .1s cubic-bezier(0, 0, 0.2, 1);
|
transition: filter .1s cubic-bezier(0, 0, 0.2, 1);
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
* preload/prefetch'ing them outside the iframe will only cause double-downloads.
|
* preload/prefetch'ing them outside the iframe will only cause double-downloads.
|
||||||
* So, the best we can do is warm up a few connections to origins that are in the critical path.
|
* So, the best we can do is warm up a few connections to origins that are in the critical path.
|
||||||
*
|
*
|
||||||
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: http://crbug.com/593267
|
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: https://crbug.com/593267
|
||||||
* But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
|
* But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
|
||||||
*/
|
*/
|
||||||
static warmConnections() {
|
static warmConnections() {
|
||||||
|
|
|
@ -213,11 +213,11 @@ class Submission(Base):
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
def thumb_url(self):
|
def thumb_url(self):
|
||||||
if self.over_18: return f"http://{site}/assets/images/nsfw.webp"
|
if self.over_18: return f"https://{site}/assets/images/nsfw.webp"
|
||||||
elif not self.url: return f"http://{site}/assets/images/{site_name}/default_text.webp"
|
elif not self.url: return f"https://{site}/assets/images/{site_name}/default_text.webp"
|
||||||
elif self.thumburl: return self.thumburl
|
elif self.thumburl: return self.thumburl
|
||||||
elif "youtu.be" in self.domain or "youtube.com" == self.domain: return f"http://{site}/assets/images/default_thumb_yt.webp"
|
elif "youtu.be" in self.domain or "youtube.com" == self.domain: return f"https://{site}/assets/images/default_thumb_yt.webp"
|
||||||
else: return f"http://{site}/assets/images/default_thumb_link.webp"
|
else: return f"https://{site}/assets/images/default_thumb_link.webp"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
|
|
|
@ -411,15 +411,15 @@ class User(Base):
|
||||||
@lazy
|
@lazy
|
||||||
def banner_url(self):
|
def banner_url(self):
|
||||||
if self.bannerurl: return self.bannerurl
|
if self.bannerurl: return self.bannerurl
|
||||||
else: return f"http://{site}/assets/images/{site_name}/preview.webp?v=3"
|
else: return f"https://{site}/assets/images/{site_name}/preview.webp?v=3"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
def profile_url(self):
|
def profile_url(self):
|
||||||
if self.agendaposter: return f"http://{site}/assets/images/defaultpictures/agendaposter/{random.randint(1, 50)}.webp?v=1"
|
if self.agendaposter: return f"https://{site}/assets/images/defaultpictures/agendaposter/{random.randint(1, 50)}.webp?v=1"
|
||||||
if self.profileurl: return self.profileurl
|
if self.profileurl: return self.profileurl
|
||||||
if "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp?v=1"
|
if "rama" in site: return f"https://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp?v=1"
|
||||||
return f"http://{site}/assets/images/default-profile-pic.webp"
|
return f"https://{site}/assets/images/default-profile-pic.webp"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
|
|
|
@ -182,7 +182,7 @@ def sanitize(sanitized, noimages=False):
|
||||||
remoji = emoji
|
remoji = emoji
|
||||||
|
|
||||||
if path.isfile(f'./files/assets/images/emojis/{remoji}.webp'):
|
if path.isfile(f'./files/assets/images/emojis/{remoji}.webp'):
|
||||||
new = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" {classes}src="http://{site}/assets/images/emojis/{remoji}.webp" >', new)
|
new = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" {classes}src="https://{site}/assets/images/emojis/{remoji}.webp" >', new)
|
||||||
|
|
||||||
if remoji in session["favorite_emojis"]: session["favorite_emojis"][remoji] += 1
|
if remoji in session["favorite_emojis"]: session["favorite_emojis"][remoji] += 1
|
||||||
else: session["favorite_emojis"][remoji] = 1
|
else: session["favorite_emojis"][remoji] = 1
|
||||||
|
@ -195,13 +195,13 @@ def sanitize(sanitized, noimages=False):
|
||||||
if emoji.startswith("!"):
|
if emoji.startswith("!"):
|
||||||
emoji = emoji[1:]
|
emoji = emoji[1:]
|
||||||
if path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
if path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||||
sanitized = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" class="emoji mirrored" src="http://{site}/assets/images/emojis/{emoji}.webp">', sanitized)
|
sanitized = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" class="emoji mirrored" src="https://{site}/assets/images/emojis/{emoji}.webp">', sanitized)
|
||||||
|
|
||||||
if emoji in session["favorite_emojis"]: session["favorite_emojis"][emoji] += 1
|
if emoji in session["favorite_emojis"]: session["favorite_emojis"][emoji] += 1
|
||||||
else: session["favorite_emojis"][emoji] = 1
|
else: session["favorite_emojis"][emoji] = 1
|
||||||
|
|
||||||
elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||||
sanitized = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" class="emoji" src="http://{site}/assets/images/emojis/{emoji}.webp">', sanitized)
|
sanitized = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" class="emoji" src="https://{site}/assets/images/emojis/{emoji}.webp">', sanitized)
|
||||||
|
|
||||||
if emoji in session["favorite_emojis"]: session["favorite_emojis"][emoji] += 1
|
if emoji in session["favorite_emojis"]: session["favorite_emojis"][emoji] += 1
|
||||||
else: session["favorite_emojis"][emoji] = 1
|
else: session["favorite_emojis"][emoji] = 1
|
||||||
|
@ -265,10 +265,10 @@ def filter_title(title):
|
||||||
if emoji.startswith("!"):
|
if emoji.startswith("!"):
|
||||||
emoji = emoji[1:]
|
emoji = emoji[1:]
|
||||||
if path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
if path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||||
title = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" height=30 src="http://{site}/assets/images/emojis/{emoji}.webp" class="mirrored">', title)
|
title = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" height=30 src="https://{site}/assets/images/emojis/{emoji}.webp" class="mirrored">', title)
|
||||||
|
|
||||||
elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||||
title = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" height=30 src="http://{site}/assets/images/emojis/{emoji}.webp">', title)
|
title = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" height=30 src="https://{site}/assets/images/emojis/{emoji}.webp">', title)
|
||||||
|
|
||||||
if len(title) > 1500: abort(400)
|
if len(title) > 1500: abort(400)
|
||||||
else: return title
|
else: return title
|
|
@ -565,7 +565,7 @@ def api_comment(v):
|
||||||
'notification': {
|
'notification': {
|
||||||
'title': f'New reply by @{v.username}',
|
'title': f'New reply by @{v.username}',
|
||||||
'body': c.body,
|
'body': c.body,
|
||||||
'deep_link': f'http://{site}/comment/{c.id}?context=9&read=true#context',
|
'deep_link': f'https://{site}/comment/{c.id}?context=9&read=true#context',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -51,7 +51,7 @@ def feeds_user(sort='hot', t='all'):
|
||||||
with tag("name"):
|
with tag("name"):
|
||||||
text(post.author.username)
|
text(post.author.username)
|
||||||
with tag("uri"):
|
with tag("uri"):
|
||||||
text(f'http://{site}/@{post.author.username}')
|
text(f'https://{site}/@{post.author.username}')
|
||||||
|
|
||||||
doc.stag("link", href=full_link(post.permalink))
|
doc.stag("link", href=full_link(post.permalink))
|
||||||
|
|
||||||
|
|
|
@ -62,12 +62,12 @@ def publish(pid, v):
|
||||||
user = g.db.query(User).filter_by(username=username).first()
|
user = g.db.query(User).filter_by(username=username).first()
|
||||||
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
|
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
|
||||||
|
|
||||||
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: http://{site}{post.permalink}")
|
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: https://{site}{post.permalink}")
|
||||||
|
|
||||||
for follow in v.followers:
|
for follow in v.followers:
|
||||||
user = get_account(follow.user_id)
|
user = get_account(follow.user_id)
|
||||||
if post.club and not user.club_allowed: continue
|
if post.club and not user.club_allowed: continue
|
||||||
send_notification(user.id, f"@{v.username} has made a new post: [{post.title}](http://{site}{post.permalink})", True)
|
send_notification(user.id, f"@{v.username} has made a new post: [{post.title}](https://{site}{post.permalink})", True)
|
||||||
|
|
||||||
cache.delete_memoized(frontlist)
|
cache.delete_memoized(frontlist)
|
||||||
|
|
||||||
|
@ -481,7 +481,7 @@ def edit_post(pid, v):
|
||||||
user = g.db.query(User).filter_by(username=username).first()
|
user = g.db.query(User).filter_by(username=username).first()
|
||||||
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
|
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
|
||||||
|
|
||||||
message = f"@{v.username} has mentioned you: http://{site}{p.permalink}"
|
message = f"@{v.username} has mentioned you: https://{site}{p.permalink}"
|
||||||
|
|
||||||
for x in notify_users: send_notification(x, message)
|
for x in notify_users: send_notification(x, message)
|
||||||
|
|
||||||
|
@ -524,8 +524,8 @@ def thumbnail_thread(pid):
|
||||||
|
|
||||||
if fragment_url.startswith("https://"):
|
if fragment_url.startswith("https://"):
|
||||||
return fragment_url
|
return fragment_url
|
||||||
elif fragment_url.startswith("http://"):
|
elif fragment_url.startswith("https://"):
|
||||||
return f"https://{fragment_url.split('http://')[1]}"
|
return f"https://{fragment_url.split('https://')[1]}"
|
||||||
elif fragment_url.startswith('//'):
|
elif fragment_url.startswith('//'):
|
||||||
return f"https:{fragment_url}"
|
return f"https:{fragment_url}"
|
||||||
elif fragment_url.startswith('/'):
|
elif fragment_url.startswith('/'):
|
||||||
|
@ -968,12 +968,12 @@ def submit_post(v):
|
||||||
user = g.db.query(User).filter_by(username=username).first()
|
user = g.db.query(User).filter_by(username=username).first()
|
||||||
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
|
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
|
||||||
|
|
||||||
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: http://{site}{new_post.permalink}")
|
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: https://{site}{new_post.permalink}")
|
||||||
|
|
||||||
for follow in v.followers:
|
for follow in v.followers:
|
||||||
user = get_account(follow.user_id)
|
user = get_account(follow.user_id)
|
||||||
if new_post.club and not user.club_allowed: continue
|
if new_post.club and not user.club_allowed: continue
|
||||||
send_notification(user.id, f"@{v.username} has made a new post: [{title}](http://{site}{new_post.permalink})", True)
|
send_notification(user.id, f"@{v.username} has made a new post: [{title}](https://{site}{new_post.permalink})", True)
|
||||||
|
|
||||||
g.db.add(new_post)
|
g.db.add(new_post)
|
||||||
g.db.flush()
|
g.db.flush()
|
||||||
|
@ -1119,7 +1119,7 @@ def submit_post(v):
|
||||||
cache.delete_memoized(frontlist)
|
cache.delete_memoized(frontlist)
|
||||||
cache.delete_memoized(User.userpagelisting)
|
cache.delete_memoized(User.userpagelisting)
|
||||||
if v.admin_level > 1 and ("[changelog]" in new_post.title or "(changelog)" in new_post.title):
|
if v.admin_level > 1 and ("[changelog]" in new_post.title or "(changelog)" in new_post.title):
|
||||||
send_message(f"http://{site}{new_post.permalink}")
|
send_message(f"https://{site}{new_post.permalink}")
|
||||||
cache.delete_memoized(changeloglist)
|
cache.delete_memoized(changeloglist)
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
|
@ -21,7 +21,7 @@ def api_flag_post(pid, v):
|
||||||
|
|
||||||
for i in re.finditer(':(.{1,30}?):', reason):
|
for i in re.finditer(':(.{1,30}?):', reason):
|
||||||
if path.isfile(f'./files/assets/images/emojis/{i.group(1)}.webp'):
|
if path.isfile(f'./files/assets/images/emojis/{i.group(1)}.webp'):
|
||||||
reason = reason.replace(f':{i.group(1)}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{i.group(1)}:" title=":{i.group(1)}:" delay="0" height=20 src="http://{site}/assets/images/emojis/{i.group(1)}.webp">')
|
reason = reason.replace(f':{i.group(1)}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{i.group(1)}:" title=":{i.group(1)}:" delay="0" height=20 src="https://{site}/assets/images/emojis/{i.group(1)}.webp">')
|
||||||
|
|
||||||
if len(reason) > 350: return {"error": f"Too long."}
|
if len(reason) > 350: return {"error": f"Too long."}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ def api_flag_comment(cid, v):
|
||||||
|
|
||||||
for i in re.finditer(':(.{1,30}?):', reason):
|
for i in re.finditer(':(.{1,30}?):', reason):
|
||||||
if path.isfile(f'./files/assets/images/emojis/{i.group(1)}.webp'):
|
if path.isfile(f'./files/assets/images/emojis/{i.group(1)}.webp'):
|
||||||
reason = reason.replace(f':{i.group(1)}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{i.group(1)}:" title=":{i.group(1)}:" delay="0" height=20 src="http://{site}/assets/images/emojis/{i.group(1)}.webp">')
|
reason = reason.replace(f':{i.group(1)}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{i.group(1)}:" title=":{i.group(1)}:" delay="0" height=20 src="https://{site}/assets/images/emojis/{i.group(1)}.webp">')
|
||||||
|
|
||||||
if len(reason) > 350: return {"error": f"Too long."}
|
if len(reason) > 350: return {"error": f"Too long."}
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ def contact(v):
|
||||||
@limiter.limit("1/second")
|
@limiter.limit("1/second")
|
||||||
@auth_required
|
@auth_required
|
||||||
def submit_contact(v):
|
def submit_contact(v):
|
||||||
message = f'This message has been sent automatically to all admins via http://{site}/contact, user email is "{v.email}"\n\nMessage:\n\n' + request.values.get("message", "")
|
message = f'This message has been sent automatically to all admins via https://{site}/contact, user email is "{v.email}"\n\nMessage:\n\n' + request.values.get("message", "")
|
||||||
send_admin(v.id, message)
|
send_admin(v.id, message)
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
return render_template("contact.html", v=v, msg="Your message has been sent.")
|
return render_template("contact.html", v=v, msg="Your message has been sent.")
|
||||||
|
|
|
@ -383,7 +383,7 @@ def message2(v, username):
|
||||||
'notification': {
|
'notification': {
|
||||||
'title': f'New message from @{v.username}',
|
'title': f'New message from @{v.username}',
|
||||||
'body': message,
|
'body': message,
|
||||||
'deep_link': f'http://{site}/notifications',
|
'deep_link': f'https://{site}/notifications',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -206,7 +206,7 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<a rel="nofollow noopener noreferrer" href="{% if 'rama' in request.host %}https://secure.transequality.org/site/Donation2?df_id=1480{% else %}/{% endif %}">
|
<a rel="nofollow noopener noreferrer" href="{% if 'rama' in request.host %}https://secure.transequality.org/site/Donation2?df_id=1480{% else %}/{% endif %}">
|
||||||
<img loading="lazy" class="banner" src="/assets/images/{{'SITE_NAME' | app_config}}/{% if v %}banner.webp{% else %}cached.webp{% endif %}?v=5" width="100%">
|
<img class="banner" src="/assets/images/{{'SITE_NAME' | app_config}}/{% if v %}banner.webp{% else %}cached.webp{% endif %}?v=5" width="100%">
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -694,7 +694,7 @@ replica-lazy-flush no
|
||||||
# If the AOF is enabled on startup Redis will load the AOF, that is the file
|
# If the AOF is enabled on startup Redis will load the AOF, that is the file
|
||||||
# with the better durability guarantees.
|
# with the better durability guarantees.
|
||||||
#
|
#
|
||||||
# Please check http://redis.io/topics/persistence for more information.
|
# Please check https://redis.io/topics/persistence for more information.
|
||||||
|
|
||||||
appendonly no
|
appendonly no
|
||||||
|
|
||||||
|
@ -721,7 +721,7 @@ appendfilename "appendonly.aof"
|
||||||
# everysec.
|
# everysec.
|
||||||
#
|
#
|
||||||
# More details please check the following article:
|
# More details please check the following article:
|
||||||
# http://antirez.com/post/redis-persistence-demystified.html
|
# https://antirez.com/post/redis-persistence-demystified.html
|
||||||
#
|
#
|
||||||
# If unsure, use "everysec".
|
# If unsure, use "everysec".
|
||||||
|
|
||||||
|
@ -933,7 +933,7 @@ lua-time-limit 5000
|
||||||
# cluster-replica-no-failover no
|
# cluster-replica-no-failover no
|
||||||
|
|
||||||
# In order to setup your cluster make sure to read the documentation
|
# In order to setup your cluster make sure to read the documentation
|
||||||
# available at http://redis.io web site.
|
# available at https://redis.io web site.
|
||||||
|
|
||||||
########################## CLUSTER DOCKER/NAT support ########################
|
########################## CLUSTER DOCKER/NAT support ########################
|
||||||
|
|
||||||
|
@ -1016,7 +1016,7 @@ latency-monitor-threshold 0
|
||||||
############################# EVENT NOTIFICATION ##############################
|
############################# EVENT NOTIFICATION ##############################
|
||||||
|
|
||||||
# Redis can notify Pub/Sub clients about events happening in the key space.
|
# Redis can notify Pub/Sub clients about events happening in the key space.
|
||||||
# This feature is documented at http://redis.io/topics/notifications
|
# This feature is documented at https://redis.io/topics/notifications
|
||||||
#
|
#
|
||||||
# For instance if keyspace events notification is enabled, and a client
|
# For instance if keyspace events notification is enabled, and a client
|
||||||
# performs a DEL operation on key "foo" stored in the Database 0, two
|
# performs a DEL operation on key "foo" stored in the Database 0, two
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue