diff options
23 files changed, 81 insertions, 103 deletions
diff --git a/include/m_database.h b/include/m_database.h index dbf8455e56..34d4b3d128 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -59,6 +59,14 @@ EXTERN_C MIR_CORE_DLL(void) db_set_safety_mode(BOOL bNewMode); EXTERN_C MIR_CORE_DLL(int) db_get_contact_count(void); +// Checks if a module doesn't contain any settings (for the contact given) + +MIR_CORE_DLL(bool) db_is_module_empty(MCONTACT hContact, const char *module); + +// Copies a module to another module for the contact given (0 by default) + +EXTERN_C MIR_CORE_DLL(int) db_copy_module(const char *szModule, const char *szNewModule, MCONTACT hContact = 0); + // Removes all settings for the specified module. // hContact is 0 for global settings or matches the concrete contact diff --git a/libs/win32/mir_core.lib b/libs/win32/mir_core.lib Binary files differindex 78d5779a36..f53831db9c 100644 --- a/libs/win32/mir_core.lib +++ b/libs/win32/mir_core.lib diff --git a/libs/win64/mir_core.lib b/libs/win64/mir_core.lib Binary files differindex de435d8700..b61080cd83 100644 --- a/libs/win64/mir_core.lib +++ b/libs/win64/mir_core.lib diff --git a/plugins/DbEditorPP/src/copymodule.cpp b/plugins/DbEditorPP/src/copymodule.cpp index a8bebffcff..12ebee4e73 100644 --- a/plugins/DbEditorPP/src/copymodule.cpp +++ b/plugins/DbEditorPP/src/copymodule.cpp @@ -3,7 +3,7 @@ void copyModule(const char *module, MCONTACT hContactFrom, MCONTACT hContactTo)
{
ModuleSettingLL msll;
- if (IsModuleEmpty(hContactFrom, module) || !EnumSettings(hContactFrom, module, &msll))
+ if (db_is_module_empty(hContactFrom, module) || !EnumSettings(hContactFrom, module, &msll))
return;
DBVARIANT dbv;
diff --git a/plugins/DbEditorPP/src/deletemodule.cpp b/plugins/DbEditorPP/src/deletemodule.cpp index 61d06228d1..9a14210a80 100644 --- a/plugins/DbEditorPP/src/deletemodule.cpp +++ b/plugins/DbEditorPP/src/deletemodule.cpp @@ -5,7 +5,7 @@ static HWND hwnd2Delete = nullptr; int deleteModule(HWND hwndParent, MCONTACT hContact, const char *module, int confirm)
{
- if (!module || IsModuleEmpty(hContact, module))
+ if (!module || db_is_module_empty(hContact, module))
return 0;
if (confirm && g_plugin.bWarnOnDelete) {
@@ -40,7 +40,7 @@ void __cdecl PopulateModuleDropListThreadFunc(void *param) while (module && working) {
moduleEmpty = 1;
// check the null
- if (!IsModuleEmpty(NULL, module->name)) {
+ if (!db_is_module_empty(NULL, module->name)) {
SendDlgItemMessageA(hwnd, IDC_CONTACTS, CB_ADDSTRING, 0, (LPARAM)module->name);
moduleEmpty = 0;
module = module->next;
@@ -48,7 +48,7 @@ void __cdecl PopulateModuleDropListThreadFunc(void *param) }
for (auto &hContact : Contacts()) {
- if (!IsModuleEmpty(hContact, module->name)) {
+ if (!db_is_module_empty(hContact, module->name)) {
SendDlgItemMessageA(hwnd, IDC_CONTACTS, CB_ADDSTRING, 0, (LPARAM)module->name);
moduleEmpty = 0;
break;
diff --git a/plugins/DbEditorPP/src/exportimport.cpp b/plugins/DbEditorPP/src/exportimport.cpp index d835bf60de..077de74188 100644 --- a/plugins/DbEditorPP/src/exportimport.cpp +++ b/plugins/DbEditorPP/src/exportimport.cpp @@ -52,7 +52,7 @@ void exportModule(MCONTACT hContact, const char *module, FILE *file) ModuleSettingLL settinglist;
ModSetLinkLinkItem *setting;
- if (IsModuleEmpty(hContact, module) || !EnumSettings(hContact, module, &settinglist))
+ if (db_is_module_empty(hContact, module) || !EnumSettings(hContact, module, &settinglist))
return;
// print the module header..
@@ -165,7 +165,7 @@ void exportDB(MCONTACT hContact, const char *module) fprintf(file, "SETTINGS:\n");
mod = modlist.first;
while (mod) {
- if (IsModuleEmpty(NULL, mod->name)) {
+ if (db_is_module_empty(NULL, mod->name)) {
mod = (ModSetLinkLinkItem *)mod->next;
continue;
}
@@ -192,7 +192,7 @@ void exportDB(MCONTACT hContact, const char *module) {
mod = modlist.first;
while (mod) {
- if (IsModuleEmpty(cc, mod->name)) {
+ if (db_is_module_empty(cc, mod->name)) {
mod = (ModSetLinkLinkItem *)mod->next;
continue;
}
@@ -218,7 +218,7 @@ void exportDB(MCONTACT hContact, const char *module) mod = modlist.first;
while (mod) {
- if (IsModuleEmpty(hContact, mod->name)) {
+ if (db_is_module_empty(hContact, mod->name)) {
mod = (ModSetLinkLinkItem *)mod->next;
continue;
}
diff --git a/plugins/DbEditorPP/src/findwindow.cpp b/plugins/DbEditorPP/src/findwindow.cpp index cf669b3970..a75ed148c4 100644 --- a/plugins/DbEditorPP/src/findwindow.cpp +++ b/plugins/DbEditorPP/src/findwindow.cpp @@ -187,7 +187,7 @@ class CFindWindowDlg : public CDlgBase for (module = ModuleList.first; module; module = module->next) {
- if (IsModuleEmpty(hContact, module->name))
+ if (db_is_module_empty(hContact, module->name))
continue;
if (fi->options & (F_SETVAL | F_SETNAME)) {
diff --git a/plugins/DbEditorPP/src/main_window.cpp b/plugins/DbEditorPP/src/main_window.cpp index 78d74c1f6e..b0b8221c22 100644 --- a/plugins/DbEditorPP/src/main_window.cpp +++ b/plugins/DbEditorPP/src/main_window.cpp @@ -530,7 +530,7 @@ void CMainDlg::onItemExpand_Modules(CCtrlTreeView::TEventInfo *ev) ModSetLinkLinkItem *module = modlist.first;
while (module && g_pMainWindow) {
- if (module->name[0] && !IsModuleEmpty(hContact, module->name))
+ if (module->name[0] && !db_is_module_empty(hContact, module->name))
insertItem(hContact, module->name, ev->nmtv->itemNew.hItem);
module = (ModSetLinkLinkItem *)module->next;
diff --git a/plugins/DbEditorPP/src/modsettingenum.cpp b/plugins/DbEditorPP/src/modsettingenum.cpp index 0a693640fa..6137fe38a8 100644 --- a/plugins/DbEditorPP/src/modsettingenum.cpp +++ b/plugins/DbEditorPP/src/modsettingenum.cpp @@ -71,15 +71,7 @@ int EnumSettings(MCONTACT hContact, const char *module, ModuleSettingLL *msll) return 1;
}
-int CheckIfModuleIsEmptyProc(const char*, void*)
-{
- return 1;
-}
-
-int IsModuleEmpty(MCONTACT hContact, const char *module)
-{
- return 0 > db_enum_settings(hContact, CheckIfModuleIsEmptyProc, module);
-}
+/////////////////////////////////////////////////////////////////////////////////////////
static int stringCompare(const char *p1, const char *p2)
{
@@ -162,7 +154,7 @@ int fixResidentSettings() for (auto &hContact : Contacts()) {
for (ModSetLinkLinkItem *module = ModuleList.first; module; module = module->next) {
- if (IsModuleEmpty(hContact, module->name))
+ if (db_is_module_empty(hContact, module->name))
continue;
ModuleSettingLL SettingList;
diff --git a/plugins/DbEditorPP/src/moduletree.cpp b/plugins/DbEditorPP/src/moduletree.cpp index c5e8c1e1a1..92f4ad3d89 100644 --- a/plugins/DbEditorPP/src/moduletree.cpp +++ b/plugins/DbEditorPP/src/moduletree.cpp @@ -75,7 +75,7 @@ int CMainDlg::doContacts(HTREEITEM contactsRoot, ModuleSettingLL *modlist, MCONT if (hSelectedContact == hContact) {
for (ModSetLinkLinkItem *module = modlist->first; module && g_pMainWindow; module = module->next) {
- if (!module->name[0] || IsModuleEmpty(hContact, module->name))
+ if (!module->name[0] || db_is_module_empty(hContact, module->name))
continue;
insertItem(hContact, module->name, contact);
}
@@ -127,7 +127,7 @@ void CMainDlg::doItems(ModuleSettingLL *modlist, int count) SetCaption(percent);
for (ModSetLinkLinkItem *module = modlist->first; module && g_pMainWindow; module = module->next) {
- if (!module->name[0] || IsModuleEmpty(hContact, module->name))
+ if (!module->name[0] || db_is_module_empty(hContact, module->name))
continue;
insertItem(hContact, module->name, item.hItem);
@@ -396,7 +396,7 @@ void __cdecl CMainDlg::PopulateModuleTreeThreadFunc(void *param) MCONTACT hContact = 0;
for (ModSetLinkLinkItem *module = modlist.first; module && g_pMainWindow; module = module->next) {
- if (!module->name[0] || IsModuleEmpty(hContact, module->name))
+ if (!module->name[0] || db_is_module_empty(hContact, module->name))
continue;
g_pMainWindow->insertItem(hContact, module->name, contact);
}
diff --git a/plugins/DbEditorPP/src/renamemodule.cpp b/plugins/DbEditorPP/src/renamemodule.cpp index 0c08ca0690..122569be71 100644 --- a/plugins/DbEditorPP/src/renamemodule.cpp +++ b/plugins/DbEditorPP/src/renamemodule.cpp @@ -3,7 +3,7 @@ int renameModule(MCONTACT hContact, const char *oldName, const char *newName)
{
ModuleSettingLL settinglist;
- if (IsModuleEmpty(hContact, oldName) || !EnumSettings(hContact, oldName, &settinglist))
+ if (db_is_module_empty(hContact, oldName) || !EnumSettings(hContact, oldName, &settinglist))
return 0;
int cnt = 0;
diff --git a/plugins/DbEditorPP/src/settinglist.cpp b/plugins/DbEditorPP/src/settinglist.cpp index eca77599a6..1893447210 100644 --- a/plugins/DbEditorPP/src/settinglist.cpp +++ b/plugins/DbEditorPP/src/settinglist.cpp @@ -335,7 +335,7 @@ void CMainDlg::PopulateSettings(MCONTACT hContact, const char *module) mir_strncpy(m_module, tmp, _countof(m_module));
ModuleSettingLL setlist;
- if (IsModuleEmpty(m_hContact, m_module) || !EnumSettings(m_hContact, m_module, &setlist))
+ if (db_is_module_empty(m_hContact, m_module) || !EnumSettings(m_hContact, m_module, &setlist))
return;
for (ModSetLinkLinkItem *setting = setlist.first; setting; setting = setting->next)
diff --git a/plugins/DbEditorPP/src/stdafx.h b/plugins/DbEditorPP/src/stdafx.h index 0934c31319..9ce98b774e 100644 --- a/plugins/DbEditorPP/src/stdafx.h +++ b/plugins/DbEditorPP/src/stdafx.h @@ -331,7 +331,6 @@ void popupWatchedVar(MCONTACT hContact, const char *module, const char *setting) int EnumModules(ModuleSettingLL *msll);
int EnumSettings(MCONTACT hContact, const char *module, ModuleSettingLL *msll);
void FreeModuleSettingLL(ModuleSettingLL *msll);
-int IsModuleEmpty(MCONTACT hContact, const char *module);
int LoadResidentSettings();
void FreeResidentSettings();
int IsResidentSetting(const char *module, const char *setting);
diff --git a/plugins/DbEditorPP/src/watchedvars.cpp b/plugins/DbEditorPP/src/watchedvars.cpp index 0155f5551e..af5fefbb46 100644 --- a/plugins/DbEditorPP/src/watchedvars.cpp +++ b/plugins/DbEditorPP/src/watchedvars.cpp @@ -87,7 +87,7 @@ void addwatchtolist(HWND hwnd, struct DBsetting *lParam) if (!lParam->setting) // add every item in the module and return
{
ModuleSettingLL settinglist;
- if (IsModuleEmpty(lParam->hContact, lParam->module) || !EnumSettings(lParam->hContact, lParam->module, &settinglist))
+ if (db_is_module_empty(lParam->hContact, lParam->module) || !EnumSettings(lParam->hContact, lParam->module, &settinglist))
return;
struct DBsetting dummy = {};
diff --git a/plugins/Popup/src/config.cpp b/plugins/Popup/src/config.cpp index 5dbcca1324..0f1a3ad934 100644 --- a/plugins/Popup/src/config.cpp +++ b/plugins/Popup/src/config.cpp @@ -103,40 +103,15 @@ void PopupPreview() //////////////////////////////////////////////////////////////////////////////////////////////
-struct EnumProcParam
-{
- LPCSTR szModule, szNewModule;
-};
-
-static int EnumProc(const char *szSetting, void *lParam)
-{
- EnumProcParam* param = (EnumProcParam*)lParam;
-
- DBVARIANT dbv;
- if (!db_get(NULL, param->szModule, szSetting, &dbv)) {
- db_set(NULL, param->szNewModule, szSetting, &dbv);
- db_free(&dbv);
- }
- return 0;
-}
-
-static void CopyModule(const char *szModule, const char *szNewModule)
-{
- EnumProcParam param = { szModule, szNewModule };
- db_enum_settings(NULL, EnumProc, szModule, ¶m);
-
- db_delete_module(0, szModule);
-}
-
void UpgradeDb()
{
if (db_get_b(0, "Compatibility", "Popup+ Opts", 0) == 1)
return;
- CopyModule("PopUp", "Popup");
- CopyModule("PopUpCLASS", "PopupCLASS");
- CopyModule("PopUpActions", "PopupActions");
- CopyModule("PopUpNotifications", "PopupNotifications");
+ db_copy_module("PopUp", "Popup");
+ db_copy_module("PopUpCLASS", "PopupCLASS");
+ db_copy_module("PopUpActions", "PopupActions");
+ db_copy_module("PopUpNotifications", "PopupNotifications");
db_set_b(0, "Compatibility", "Popup+ Opts", 1);
}
diff --git a/plugins/UserInfoEx/src/ex_import/dlg_ExImModules.cpp b/plugins/UserInfoEx/src/ex_import/dlg_ExImModules.cpp index 46abcece72..666fd84b78 100644 --- a/plugins/UserInfoEx/src/ex_import/dlg_ExImModules.cpp +++ b/plugins/UserInfoEx/src/ex_import/dlg_ExImModules.cpp @@ -274,7 +274,7 @@ INT_PTR CALLBACK SelectModulesToExport_DlgProc(HWND hDlg, UINT uMsg, WPARAM wPar {
for (auto &hContact: Contacts()) {
// ignore empty modules
- if (!DB::Module::IsEmpty(hContact, p)) {
+ if (!db_is_module_empty(hContact, p)) {
pszProto = Proto_GetBaseAccountName(hContact);
// Filter by mode
switch (pDat->ExImContact->Typ) {
@@ -311,7 +311,7 @@ INT_PTR CALLBACK SelectModulesToExport_DlgProc(HWND hDlg, UINT uMsg, WPARAM wPar } // end TRUE = All Contacts
// module must exist in the selected contact
- else if (!DB::Module::IsEmpty(pDat->ExImContact->hContact, p) && (!pDat->ExImContact->hContact || mir_strcmpi(p, pszProto)) && mir_strcmpi(p, USERINFO)) {
+ else if (!db_is_module_empty(pDat->ExImContact->hContact, p) && (!pDat->ExImContact->hContact || mir_strcmpi(p, pszProto)) && mir_strcmpi(p, USERINFO)) {
ExportTree_AddItem(hTree, hItemOptional, (LPSTR)p, bImagesLoaded, 1);
}
}
diff --git a/plugins/UserInfoEx/src/mir_db.cpp b/plugins/UserInfoEx/src/mir_db.cpp index f10a850566..ad76d4b4c5 100644 --- a/plugins/UserInfoEx/src/mir_db.cpp +++ b/plugins/UserInfoEx/src/mir_db.cpp @@ -56,21 +56,6 @@ uint32_t WhenAdded(uint32_t dwUIN, LPCSTR) namespace Module {
/**
-* Deletes all settings in the module.
-* @param hContact - handle to the contact
-* @param pszModule - the module to delete the setting from (e.g. USERINFO)
-* return: nothing
-**/
-
-void Delete(MCONTACT hContact, LPCSTR pszModule)
-{
- CEnumList Settings;
- if (!Settings.EnumSettings(hContact, pszModule))
- for (auto &it : Settings)
- db_unset(hContact, pszModule, it);
-}
-
-/**
* Enum Proc for DBModule_IsEmpty
* @param pszSetting - the setting
* @param lParam - DBCONTACTENUMSETTINGS - (LPARAM)&dbces
@@ -83,19 +68,6 @@ static int IsEmptyEnumProc(LPCSTR, void*) }
/**
-* This function tests, whether a module is empty for the given contact or not
-* @param hContact - handle to the contact
-* @param pszModule - the module to read the setting from (e.g. USERINFO)
-* @retval TRUE - the module is empty
-* @retval FALSE - the module contains settings
-**/
-
-bool IsEmpty(MCONTACT hContact, LPCSTR pszModule)
-{
- return 0 > db_enum_settings(hContact, IsEmptyEnumProc, pszModule);
-}
-
-/**
* This function tests, whether a module belongs to a metacontact protocol
* @param pszModule - the module to read the setting from (e.g. USERINFO)
* @retval TRUE - the module belongs to a metacontact protocol
diff --git a/plugins/UserInfoEx/src/mir_db.h b/plugins/UserInfoEx/src/mir_db.h index 6ede82c18f..e00052a450 100644 --- a/plugins/UserInfoEx/src/mir_db.h +++ b/plugins/UserInfoEx/src/mir_db.h @@ -33,8 +33,6 @@ namespace Contact { } /* namespace Contact */
namespace Module {
- void Delete(MCONTACT hContact, LPCSTR pszModule);
- bool IsEmpty(MCONTACT hContact, LPCSTR pszModule);
bool IsMeta(LPCSTR pszModule);
bool IsMetaAndScan(LPCSTR pszModule);
diff --git a/plugins/UserInfoEx/src/psp_options.cpp b/plugins/UserInfoEx/src/psp_options.cpp index dac4bbee06..26838261ec 100644 --- a/plugins/UserInfoEx/src/psp_options.cpp +++ b/plugins/UserInfoEx/src/psp_options.cpp @@ -419,8 +419,8 @@ static INT_PTR CALLBACK DlgProc_AdvancedOpts(HWND hDlg, UINT uMsg, WPARAM wParam db_unset(0, "SkinIcons", s);
// delete global settings
- DB::Module::Delete(NULL, USERINFO"Ex");
- DB::Module::Delete(NULL, USERINFO"ExW");
+ db_delete_module(NULL, USERINFO"Ex");
+ db_delete_module(NULL, USERINFO"ExW");
// delete old contactsettings
for (auto &hContact : Contacts()) {
@@ -434,8 +434,8 @@ static INT_PTR CALLBACK DlgProc_AdvancedOpts(HWND hDlg, UINT uMsg, WPARAM wParam db_unset(hContact, USERINFO, "RemindDaysErlier");
db_unset(hContact, USERINFO, "vCardPath");
- DB::Module::Delete(hContact, USERINFO"Ex");
- DB::Module::Delete(hContact, USERINFO"ExW");
+ db_delete_module(hContact, USERINFO"Ex");
+ db_delete_module(hContact, USERINFO"ExW");
}
SendMessage(GetParent(hDlg), PSM_FORCECHANGED, NULL, NULL);
diff --git a/src/mir_app/src/db_ini.cpp b/src/mir_app/src/db_ini.cpp index 978c802679..73ca514756 100644 --- a/src/mir_app/src/db_ini.cpp +++ b/src/mir_app/src/db_ini.cpp @@ -421,16 +421,8 @@ LBL_NewLine: case 'l':
case 'L':
case '-':
- if (szValue[1] == '*') {
- LIST<char> arSettings(1);
- ESFDParam param = { &arSettings, szName };
- db_enum_settings(0, EnumSettingsForDeletion, szSection, ¶m);
-
- for (auto &it : arSettings) {
- db_unset(0, szSection, it);
- mir_free(it);
- }
- }
+ if (szValue[1] == '*')
+ db_delete_module(0, szSection);
db_unset(0, szSection, szName);
break;
case 'e':
diff --git a/src/mir_core/src/db.cpp b/src/mir_core/src/db.cpp index ecd55c9be3..cb95ebb286 100644 --- a/src/mir_core/src/db.cpp +++ b/src/mir_core/src/db.cpp @@ -51,6 +51,44 @@ MIR_CORE_DLL(int) db_delete_module(MCONTACT hContact, const char *szModuleName) } ///////////////////////////////////////////////////////////////////////////////////////// + +static int CheckIfModuleIsEmptyProc(const char *, void *) +{ + return 1; +} + +MIR_CORE_DLL(bool) db_is_module_empty(MCONTACT hContact, const char *szModule) +{ + return (g_pCurrDb) ? g_pCurrDb->EnumContactSettings(hContact, CheckIfModuleIsEmptyProc, szModule, 0) < 0 : true; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +struct EnumProcParam +{ + MCONTACT hContact; + LPCSTR szModule, szNewModule; +}; + +static int EnumProc(const char *szSetting, void *lParam) +{ + EnumProcParam *param = (EnumProcParam *)lParam; + + DBVARIANT dbv; + if (!db_get(param->hContact, param->szModule, szSetting, &dbv)) { + db_set(param->hContact, param->szNewModule, szSetting, &dbv); + db_free(&dbv); + } + return 0; +} + +MIR_CORE_DLL(int) db_copy_module(const char *szModule, const char *szNewModule, MCONTACT hContact) +{ + EnumProcParam param = { hContact, szModule, szNewModule }; + return db_enum_settings(hContact, EnumProc, szModule, ¶m); +} + +///////////////////////////////////////////////////////////////////////////////////////// // contact functions MIR_CORE_DLL(MCONTACT) db_add_contact(void) @@ -93,7 +131,7 @@ MIR_CORE_DLL(int) db_enum_residents(DBMODULEENUMPROC pFunc, void *param) return (g_pCurrDb) ? g_pCurrDb->EnumResidentSettings(pFunc, param) : 0; } -EXTERN_C MIR_CORE_DLL(int) db_enum_settings(MCONTACT hContact, DBSETTINGENUMPROC pFunc, const char *szModule, void *param) +MIR_CORE_DLL(int) db_enum_settings(MCONTACT hContact, DBSETTINGENUMPROC pFunc, const char *szModule, void *param) { return (g_pCurrDb) ? g_pCurrDb->EnumContactSettings(hContact, pFunc, szModule, param) : 0; } diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def index b9c1d532ca..70f0dcd951 100644 --- a/src/mir_core/src/mir_core.def +++ b/src/mir_core/src/mir_core.def @@ -1511,3 +1511,5 @@ TimeZone_GetSystemTime @1692 ?IsPrefixHex@XMLUtil@tinyxml2@@SA_NPBD@Z @1733 NONAME
?PrepareForNewNode@XMLPrinter@tinyxml2@@AAEX_N@Z @1734 NONAME
?QueryAttribute@XMLElement@tinyxml2@@QBE?AW4XMLError@2@PBDPAPBD@Z @1735 NONAME
+db_copy_module @1736
+?db_is_module_empty@@YG_NIPBD@Z @1737 NONAME
diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def index a25eee9663..0fd20a620b 100644 --- a/src/mir_core/src/mir_core64.def +++ b/src/mir_core/src/mir_core64.def @@ -1511,3 +1511,5 @@ TimeZone_GetSystemTime @1692 ?IsPrefixHex@XMLUtil@tinyxml2@@SA_NPEBD@Z @1733 NONAME
?PrepareForNewNode@XMLPrinter@tinyxml2@@AEAAX_N@Z @1734 NONAME
?QueryAttribute@XMLElement@tinyxml2@@QEBA?AW4XMLError@2@PEBDPEAPEBD@Z @1735 NONAME
+db_copy_module @1736
+?db_is_module_empty@@YA_NIPEBD@Z @1737 NONAME
|