mirror of https://gitlab.com/bashrc2/epicyon
Minimize all images on edit profile screen
parent
f81e2f32ae
commit
19a1676ee8
26
daemon.py
26
daemon.py
|
@ -264,6 +264,8 @@ from languages import set_actor_languages
|
||||||
from languages import get_understood_languages
|
from languages import get_understood_languages
|
||||||
from like import update_likes_collection
|
from like import update_likes_collection
|
||||||
from reaction import update_reaction_collection
|
from reaction import update_reaction_collection
|
||||||
|
from utils import load_min_images_for_accounts
|
||||||
|
from utils import set_minimize_all_images
|
||||||
from utils import get_json_content_from_accept
|
from utils import get_json_content_from_accept
|
||||||
from utils import remove_eol
|
from utils import remove_eol
|
||||||
from utils import text_in_file
|
from utils import text_in_file
|
||||||
|
@ -6961,6 +6963,25 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
'unable to delete ' +
|
'unable to delete ' +
|
||||||
hide_like_button_file)
|
hide_like_button_file)
|
||||||
|
|
||||||
|
# Minimize all images from edit profile screen
|
||||||
|
minimize_all_images = False
|
||||||
|
if fields.get('minimizeAllImages'):
|
||||||
|
if fields['minimizeAllImages'] == 'on':
|
||||||
|
minimize_all_images = True
|
||||||
|
min_img_acct = self.server.min_images_for_accounts
|
||||||
|
set_minimize_all_images(base_dir,
|
||||||
|
nickname, domain,
|
||||||
|
True, min_img_acct)
|
||||||
|
print('min_images_for_accounts: ' +
|
||||||
|
str(min_img_acct))
|
||||||
|
if not minimize_all_images:
|
||||||
|
min_img_acct = self.server.min_images_for_accounts
|
||||||
|
set_minimize_all_images(base_dir,
|
||||||
|
nickname, domain,
|
||||||
|
False, min_img_acct)
|
||||||
|
print('min_images_for_accounts: ' +
|
||||||
|
str(min_img_acct))
|
||||||
|
|
||||||
# hide Reaction button
|
# hide Reaction button
|
||||||
hide_reaction_button_file = \
|
hide_reaction_button_file = \
|
||||||
acct_dir(base_dir, nickname, domain) + \
|
acct_dir(base_dir, nickname, domain) + \
|
||||||
|
@ -15197,7 +15218,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
default_reply_interval_hrs,
|
default_reply_interval_hrs,
|
||||||
self.server.cw_lists,
|
self.server.cw_lists,
|
||||||
self.server.lists_enabled,
|
self.server.lists_enabled,
|
||||||
self.server.system_language)
|
self.server.system_language,
|
||||||
|
self.server.min_images_for_accounts)
|
||||||
if msg:
|
if msg:
|
||||||
msg = msg.encode('utf-8')
|
msg = msg.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
@ -21334,7 +21356,7 @@ def run_daemon(map_format: str,
|
||||||
assert not scan_themes_for_scripts(base_dir)
|
assert not scan_themes_for_scripts(base_dir)
|
||||||
|
|
||||||
# which accounts should minimize all attached images by default
|
# which accounts should minimize all attached images by default
|
||||||
httpd.min_images_for_accounts = []
|
httpd.min_images_for_accounts = load_min_images_for_accounts(base_dir)
|
||||||
|
|
||||||
# caches css files
|
# caches css files
|
||||||
httpd.css_cache = {}
|
httpd.css_cache = {}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "رفض حسابات البريد العشوائي",
|
"Reject spam accounts": "رفض حسابات البريد العشوائي",
|
||||||
"User Manual": "دليل الاستخدام",
|
"User Manual": "دليل الاستخدام",
|
||||||
"Allow announces": "تعلن السماح",
|
"Allow announces": "تعلن السماح",
|
||||||
"Send": "إرسال"
|
"Send": "إرسال",
|
||||||
|
"Minimize all images": "تصغير كل الصور"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "স্প্যাম অ্যাকাউন্ট প্রত্যাখ্যান করুন",
|
"Reject spam accounts": "স্প্যাম অ্যাকাউন্ট প্রত্যাখ্যান করুন",
|
||||||
"User Manual": "ব্যবহার বিধি",
|
"User Manual": "ব্যবহার বিধি",
|
||||||
"Allow announces": "ঘোষণার অনুমতি দিন",
|
"Allow announces": "ঘোষণার অনুমতি দিন",
|
||||||
"Send": "পাঠান"
|
"Send": "পাঠান",
|
||||||
|
"Minimize all images": "সমস্ত ছবি ছোট করুন"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Rebutja els comptes de correu brossa",
|
"Reject spam accounts": "Rebutja els comptes de correu brossa",
|
||||||
"User Manual": "Manual d'usuari",
|
"User Manual": "Manual d'usuari",
|
||||||
"Allow announces": "Permet anuncis",
|
"Allow announces": "Permet anuncis",
|
||||||
"Send": "Enviar"
|
"Send": "Enviar",
|
||||||
|
"Minimize all images": "Minimitzar totes les imatges"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Gwrthod cyfrifon sbam",
|
"Reject spam accounts": "Gwrthod cyfrifon sbam",
|
||||||
"User Manual": "Llawlyfr Defnyddiwr",
|
"User Manual": "Llawlyfr Defnyddiwr",
|
||||||
"Allow announces": "Caniatáu cyhoeddiadau",
|
"Allow announces": "Caniatáu cyhoeddiadau",
|
||||||
"Send": "Anfon"
|
"Send": "Anfon",
|
||||||
|
"Minimize all images": "Lleihau pob delwedd"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Gwrthod cyfrifon sbam",
|
"Reject spam accounts": "Gwrthod cyfrifon sbam",
|
||||||
"User Manual": "Benutzerhandbuch",
|
"User Manual": "Benutzerhandbuch",
|
||||||
"Allow announces": "Zulassen kündigt an",
|
"Allow announces": "Zulassen kündigt an",
|
||||||
"Send": "Senden"
|
"Send": "Senden",
|
||||||
|
"Minimize all images": "Alle Bilder minimieren"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Gwrthod cyfrifon sbam",
|
"Reject spam accounts": "Gwrthod cyfrifon sbam",
|
||||||
"User Manual": "Εγχειρίδιο χρήστη",
|
"User Manual": "Εγχειρίδιο χρήστη",
|
||||||
"Allow announces": "Allow ανακοινώνει",
|
"Allow announces": "Allow ανακοινώνει",
|
||||||
"Send": "Στείλετε"
|
"Send": "Στείλετε",
|
||||||
|
"Minimize all images": "Ελαχιστοποίηση όλων των εικόνων"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Reject spam accounts",
|
"Reject spam accounts": "Reject spam accounts",
|
||||||
"User Manual": "User Manual",
|
"User Manual": "User Manual",
|
||||||
"Allow announces": "Allow announces",
|
"Allow announces": "Allow announces",
|
||||||
"Send": "Send"
|
"Send": "Send",
|
||||||
|
"Minimize all images": "Minimize all images"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Rechazar cuentas de spam",
|
"Reject spam accounts": "Rechazar cuentas de spam",
|
||||||
"User Manual": "Manual de usuario",
|
"User Manual": "Manual de usuario",
|
||||||
"Allow announces": "Permitir anuncios",
|
"Allow announces": "Permitir anuncios",
|
||||||
"Send": "Enviar"
|
"Send": "Enviar",
|
||||||
|
"Minimize all images": "Minimizar todas las imágenes"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Rejeter les comptes de spam",
|
"Reject spam accounts": "Rejeter les comptes de spam",
|
||||||
"User Manual": "Manuel de l'Utilisateur",
|
"User Manual": "Manuel de l'Utilisateur",
|
||||||
"Allow announces": "Autoriser les annonces",
|
"Allow announces": "Autoriser les annonces",
|
||||||
"Send": "Envoyer"
|
"Send": "Envoyer",
|
||||||
|
"Minimize all images": "Réduire toutes les images"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Diúltaigh cuntais turscair",
|
"Reject spam accounts": "Diúltaigh cuntais turscair",
|
||||||
"User Manual": "Lámhleabhar Úsáideora",
|
"User Manual": "Lámhleabhar Úsáideora",
|
||||||
"Allow announces": "Ceadaigh fógraí",
|
"Allow announces": "Ceadaigh fógraí",
|
||||||
"Send": "Seol"
|
"Send": "Seol",
|
||||||
|
"Minimize all images": "Íoslaghdaigh gach íomhá"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "स्पैम खातों को अस्वीकार करें",
|
"Reject spam accounts": "स्पैम खातों को अस्वीकार करें",
|
||||||
"User Manual": "उपयोगकर्ता पुस्तिका",
|
"User Manual": "उपयोगकर्ता पुस्तिका",
|
||||||
"Allow announces": "घोषणा की अनुमति दें",
|
"Allow announces": "घोषणा की अनुमति दें",
|
||||||
"Send": "भेजना"
|
"Send": "भेजना",
|
||||||
|
"Minimize all images": "सभी छवियों को छोटा करें"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Rifiuta gli account spam",
|
"Reject spam accounts": "Rifiuta gli account spam",
|
||||||
"User Manual": "Manuale d'uso",
|
"User Manual": "Manuale d'uso",
|
||||||
"Allow announces": "Consenti annunci",
|
"Allow announces": "Consenti annunci",
|
||||||
"Send": "Inviare"
|
"Send": "Inviare",
|
||||||
|
"Minimize all images": "Riduci a icona tutte le immagini"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "スパムアカウントを拒否",
|
"Reject spam accounts": "スパムアカウントを拒否",
|
||||||
"User Manual": "ユーザーマニュアル",
|
"User Manual": "ユーザーマニュアル",
|
||||||
"Allow announces": "アナウンスを許可",
|
"Allow announces": "アナウンスを許可",
|
||||||
"Send": "送信"
|
"Send": "送信",
|
||||||
|
"Minimize all images": "すべての画像を最小化"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "스팸 계정 거부",
|
"Reject spam accounts": "스팸 계정 거부",
|
||||||
"User Manual": "사용자 매뉴얼",
|
"User Manual": "사용자 매뉴얼",
|
||||||
"Allow announces": "공지 허용",
|
"Allow announces": "공지 허용",
|
||||||
"Send": "보내다"
|
"Send": "보내다",
|
||||||
|
"Minimize all images": "모든 이미지 최소화"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Hesabên spam red bikin",
|
"Reject spam accounts": "Hesabên spam red bikin",
|
||||||
"User Manual": "Manual Bikarhêner",
|
"User Manual": "Manual Bikarhêner",
|
||||||
"Allow announces": "Destûr dide ragihandin",
|
"Allow announces": "Destûr dide ragihandin",
|
||||||
"Send": "Şandin"
|
"Send": "Şandin",
|
||||||
|
"Minimize all images": "Hemî wêneyan kêm bikin"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Spamaccounts afwijzen",
|
"Reject spam accounts": "Spamaccounts afwijzen",
|
||||||
"User Manual": "Handleiding",
|
"User Manual": "Handleiding",
|
||||||
"Allow announces": "Aankondigingen toestaan",
|
"Allow announces": "Aankondigingen toestaan",
|
||||||
"Send": "Versturen"
|
"Send": "Versturen",
|
||||||
|
"Minimize all images": "Alle afbeeldingen minimaliseren"
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,5 +593,6 @@
|
||||||
"Reject spam accounts": "Reject spam accounts",
|
"Reject spam accounts": "Reject spam accounts",
|
||||||
"User Manual": "User Manual",
|
"User Manual": "User Manual",
|
||||||
"Allow announces": "Allow announces",
|
"Allow announces": "Allow announces",
|
||||||
"Send": "Send"
|
"Send": "Send",
|
||||||
|
"Minimize all images": "Minimize all images"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Odrzuć konta spamowe",
|
"Reject spam accounts": "Odrzuć konta spamowe",
|
||||||
"User Manual": "Instrukcja obsługi",
|
"User Manual": "Instrukcja obsługi",
|
||||||
"Allow announces": "Zezwól na ogłoszenia",
|
"Allow announces": "Zezwól na ogłoszenia",
|
||||||
"Send": "Wysłać"
|
"Send": "Wysłać",
|
||||||
|
"Minimize all images": "Zminimalizuj wszystkie obrazy"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Rejeitar contas de spam",
|
"Reject spam accounts": "Rejeitar contas de spam",
|
||||||
"User Manual": "Manual do usuário",
|
"User Manual": "Manual do usuário",
|
||||||
"Allow announces": "Permitir anúncios",
|
"Allow announces": "Permitir anúncios",
|
||||||
"Send": "Mandar"
|
"Send": "Mandar",
|
||||||
|
"Minimize all images": "Minimize todas as imagens"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Отклонить спам-аккаунты",
|
"Reject spam accounts": "Отклонить спам-аккаунты",
|
||||||
"User Manual": "Руководство пользователя",
|
"User Manual": "Руководство пользователя",
|
||||||
"Allow announces": "Разрешить объявления",
|
"Allow announces": "Разрешить объявления",
|
||||||
"Send": "Отправлять"
|
"Send": "Отправлять",
|
||||||
|
"Minimize all images": "Свернуть все изображения"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Kataa akaunti za barua taka",
|
"Reject spam accounts": "Kataa akaunti za barua taka",
|
||||||
"User Manual": "Mwongozo wa mtumiaji",
|
"User Manual": "Mwongozo wa mtumiaji",
|
||||||
"Allow announces": "Ruhusu matangazo",
|
"Allow announces": "Ruhusu matangazo",
|
||||||
"Send": "Tuma"
|
"Send": "Tuma",
|
||||||
|
"Minimize all images": "Punguza picha zote"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Spam hesapları reddet",
|
"Reject spam accounts": "Spam hesapları reddet",
|
||||||
"User Manual": "Kullanım kılavuzu",
|
"User Manual": "Kullanım kılavuzu",
|
||||||
"Allow announces": "Duyurulara izin ver",
|
"Allow announces": "Duyurulara izin ver",
|
||||||
"Send": "Göndermek"
|
"Send": "Göndermek",
|
||||||
|
"Minimize all images": "Tüm görüntüleri simge durumuna küçült"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "Відхилити спам-акаунти",
|
"Reject spam accounts": "Відхилити спам-акаунти",
|
||||||
"User Manual": "Посібник користувача",
|
"User Manual": "Посібник користувача",
|
||||||
"Allow announces": "Дозволити оголошення",
|
"Allow announces": "Дозволити оголошення",
|
||||||
"Send": "Надіслати"
|
"Send": "Надіслати",
|
||||||
|
"Minimize all images": "Згорнути всі зображення"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "אָפּוואַרפן ספּאַם אַקאַונץ",
|
"Reject spam accounts": "אָפּוואַרפן ספּאַם אַקאַונץ",
|
||||||
"User Manual": "באנוצער אנווייזער",
|
"User Manual": "באנוצער אנווייזער",
|
||||||
"Allow announces": "לאָזן אַנאַונסיז",
|
"Allow announces": "לאָזן אַנאַונסיז",
|
||||||
"Send": "שיקן"
|
"Send": "שיקן",
|
||||||
|
"Minimize all images": "מינאַמייז אַלע בילדער"
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,5 +597,6 @@
|
||||||
"Reject spam accounts": "拒绝垃圾邮件帐户",
|
"Reject spam accounts": "拒绝垃圾邮件帐户",
|
||||||
"User Manual": "用户手册",
|
"User Manual": "用户手册",
|
||||||
"Allow announces": "לאָזן אַנאַונסיז",
|
"Allow announces": "לאָזן אַנאַונסיז",
|
||||||
"Send": "发送"
|
"Send": "发送",
|
||||||
|
"Minimize all images": "最小化所有图像"
|
||||||
}
|
}
|
||||||
|
|
44
utils.py
44
utils.py
|
@ -3951,3 +3951,47 @@ def dont_speak_hashtags(content: str) -> str:
|
||||||
return content
|
return content
|
||||||
return content.replace('>#<span',
|
return content.replace('>#<span',
|
||||||
'><span aria-hidden="true">#</span><span')
|
'><span aria-hidden="true">#</span><span')
|
||||||
|
|
||||||
|
|
||||||
|
def load_min_images_for_accounts(base_dir: str) -> []:
|
||||||
|
"""Loads a list of nicknames for accounts where all images should
|
||||||
|
be minimized by default
|
||||||
|
"""
|
||||||
|
min_images_for_accounts = []
|
||||||
|
for subdir, dirs, _ in os.walk(base_dir + '/accounts'):
|
||||||
|
for account in dirs:
|
||||||
|
if not is_account_dir(account):
|
||||||
|
continue
|
||||||
|
filename = os.path.join(subdir, account) + '/.minimize_all_images'
|
||||||
|
if os.path.isfile(filename):
|
||||||
|
min_images_for_accounts.append(account.split('@')[0])
|
||||||
|
break
|
||||||
|
return min_images_for_accounts
|
||||||
|
|
||||||
|
|
||||||
|
def set_minimize_all_images(base_dir: str,
|
||||||
|
nickname: str, domain: str,
|
||||||
|
minimize: bool,
|
||||||
|
min_images_for_accounts: []) -> None:
|
||||||
|
"""Add of remove a file indicating that all images for an account
|
||||||
|
should be minimized by default
|
||||||
|
"""
|
||||||
|
filename = acct_dir(base_dir, nickname, domain) + '/.minimize_all_images'
|
||||||
|
if minimize:
|
||||||
|
if nickname not in min_images_for_accounts:
|
||||||
|
min_images_for_accounts.append(nickname)
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
try:
|
||||||
|
with open(filename, 'w+', encoding='utf-8') as fp_min:
|
||||||
|
fp_min.write('\n')
|
||||||
|
except OSError:
|
||||||
|
print('EX: unable to write ' + filename)
|
||||||
|
return
|
||||||
|
|
||||||
|
if nickname in min_images_for_accounts:
|
||||||
|
min_images_for_accounts.remove(nickname)
|
||||||
|
if os.path.isfile(filename):
|
||||||
|
try:
|
||||||
|
os.remove(filename)
|
||||||
|
except OSError:
|
||||||
|
print('EX: unable to delete ' + filename)
|
||||||
|
|
|
@ -2154,7 +2154,9 @@ def _html_edit_profile_options(is_admin: bool,
|
||||||
notify_likes: str, notify_reactions: str,
|
notify_likes: str, notify_reactions: str,
|
||||||
hide_like_button: str,
|
hide_like_button: str,
|
||||||
hide_reaction_button: str,
|
hide_reaction_button: str,
|
||||||
translate: {}, bold_reading: bool) -> str:
|
translate: {}, bold_reading: bool,
|
||||||
|
nickname: str,
|
||||||
|
min_images_for_accounts: []) -> str:
|
||||||
"""option checkboxes section of edit profile screen
|
"""option checkboxes section of edit profile screen
|
||||||
"""
|
"""
|
||||||
edit_profile_form = ' <div class="container">\n'
|
edit_profile_form = ' <div class="container">\n'
|
||||||
|
@ -2192,6 +2194,14 @@ def _html_edit_profile_options(is_admin: bool,
|
||||||
bold_str = bold_reading_string(translate['Bold reading'])
|
bold_str = bold_reading_string(translate['Bold reading'])
|
||||||
edit_profile_form += \
|
edit_profile_form += \
|
||||||
edit_check_box(bold_str, 'boldReading', bold_reading)
|
edit_check_box(bold_str, 'boldReading', bold_reading)
|
||||||
|
minimize_all_images = False
|
||||||
|
if nickname in min_images_for_accounts:
|
||||||
|
minimize_all_images = True
|
||||||
|
minimize_all_images_str = \
|
||||||
|
bold_reading_string(translate['Minimize all images'])
|
||||||
|
edit_profile_form += \
|
||||||
|
edit_check_box(minimize_all_images_str, 'minimizeAllImages',
|
||||||
|
minimize_all_images)
|
||||||
edit_profile_form += ' </div>\n'
|
edit_profile_form += ' </div>\n'
|
||||||
return edit_profile_form
|
return edit_profile_form
|
||||||
|
|
||||||
|
@ -2353,7 +2363,8 @@ def html_edit_profile(server, translate: {},
|
||||||
access_keys: {},
|
access_keys: {},
|
||||||
default_reply_interval_hrs: int,
|
default_reply_interval_hrs: int,
|
||||||
cw_lists: {}, lists_enabled: str,
|
cw_lists: {}, lists_enabled: str,
|
||||||
system_language: str) -> str:
|
system_language: str,
|
||||||
|
min_images_for_accounts: []) -> str:
|
||||||
"""Shows the edit profile screen
|
"""Shows the edit profile screen
|
||||||
"""
|
"""
|
||||||
path = path.replace('/inbox', '').replace('/outbox', '')
|
path = path.replace('/inbox', '').replace('/outbox', '')
|
||||||
|
@ -2547,7 +2558,8 @@ def html_edit_profile(server, translate: {},
|
||||||
remove_twitter,
|
remove_twitter,
|
||||||
notify_likes, notify_reactions,
|
notify_likes, notify_reactions,
|
||||||
hide_like_button, hide_reaction_button,
|
hide_like_button, hide_reaction_button,
|
||||||
translate, bold_reading)
|
translate, bold_reading,
|
||||||
|
nickname, min_images_for_accounts)
|
||||||
|
|
||||||
# Contact information
|
# Contact information
|
||||||
edit_profile_form += \
|
edit_profile_form += \
|
||||||
|
|
Loading…
Reference in New Issue