ソースを参照

Modules updates.

AntonLV 4 年 前
親
コミット
39fb56ba48
100 ファイル変更、12029 行追加、0 行削除
  1. 55 0
      modules/boonex/ads/updates/13.0.3_13.0.4/install/config.php
  2. 13 0
      modules/boonex/ads/updates/13.0.3_13.0.4/install/installer.php
  3. 151 0
      modules/boonex/ads/updates/13.0.3_13.0.4/source/install/config.php
  4. 26 0
      modules/boonex/ads/updates/13.0.3_13.0.4/source/template/form_ghost_template.html
  5. 51 0
      modules/boonex/albums/updates/13.0.1_13.0.2/install/config.php
  6. 13 0
      modules/boonex/albums/updates/13.0.1_13.0.2/install/installer.php
  7. 143 0
      modules/boonex/albums/updates/13.0.1_13.0.2/source/install/config.php
  8. 25 0
      modules/boonex/albums/updates/13.0.1_13.0.2/source/template/form_ghost_template.html
  9. 28 0
      modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit.html
  10. 17 0
      modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit_gallery.html
  11. 24 0
      modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit_media.html
  12. 23 0
      modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit_media_gallery.html
  13. 137 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/install/config.php
  14. 26 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/install/installer.php
  15. 5 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/install/langs/en.xml
  16. 9 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/install/sql/enable.sql
  17. 7 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/install/sql/install.sql
  18. 142 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/classes/BxArtificerAlertsResponse.php
  19. 43 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/classes/BxArtificerStudioOptions.php
  20. 54 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/classes/BxArtificerStudioPage.php
  21. 102 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_forum/css/main.css
  22. 1 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_forum/score_do_vote_label.html
  23. 4 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_polls/css/main.css
  24. 351 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/css/view.css
  25. 5 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_hor_bx_timeline_menu_item_actions.html
  26. 13 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_item_hor.html
  27. 11 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_item_ver.html
  28. 7 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_ver_bx_timeline_menu_item_manage.html
  29. 18 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_vertical_bx_timeline_menu_item_share.html
  30. 102 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_general/css/main.css
  31. 268 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_profile/css/main.css
  32. 6 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_profile/menu_custom_actions.html
  33. 4 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_profile/menu_custom_item_actions.html
  34. 310 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/common.css
  35. 370 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/forms.css
  36. 110 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/general.css
  37. 219 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/menu.css
  38. 14 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/menu_horizontal.html
  39. 13 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/menu_toolbar.html
  40. 118 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/pt_application.html
  41. 68 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/config.php
  42. 50 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/langs/en.xml
  43. 6 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/sql/enable.sql
  44. 49 0
      modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/sql/install.sql
  45. 51 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/install/config.php
  46. 13 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/install/installer.php
  47. 2 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/install/sql/enable.sql
  48. 256 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/source/classes/BxAttendantModule.php
  49. 119 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/source/classes/BxAttendantTemplate.php
  50. 77 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/source/install/config.php
  51. 35 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/source/install/sql/enable.sql
  52. 75 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/source/js/main.js
  53. 22 0
      modules/boonex/attendant/updates/13.0.1_13.0.2/source/template/popup_recommended.html
  54. 51 0
      modules/boonex/credits/updates/13.0.2_13.0.3/install/config.php
  55. 13 0
      modules/boonex/credits/updates/13.0.2_13.0.3/install/installer.php
  56. 1096 0
      modules/boonex/credits/updates/13.0.2_13.0.3/source/classes/BxCreditsModule.php
  57. 77 0
      modules/boonex/credits/updates/13.0.2_13.0.3/source/install/config.php
  58. 51 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/install/config.php
  59. 26 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/install/installer.php
  60. 929 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/css/default.less
  61. 344 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/css/menu.less
  62. 5 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/designbox_10.html
  63. 5 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/designbox_13.html
  64. 5 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/designbox_3.html
  65. 68 0
      modules/boonex/decorous/updates/13.0.4_13.0.5/source/install/config.php
  66. 51 0
      modules/boonex/events/updates/13.0.3_13.0.4/install/config.php
  67. 13 0
      modules/boonex/events/updates/13.0.3_13.0.4/install/installer.php
  68. 301 0
      modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsConfig.php
  69. 45 0
      modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsMenuSnippetMeta.php
  70. 115 0
      modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsMenuViewActionsAll.php
  71. 493 0
      modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsModule.php
  72. 55 0
      modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsTemplate.php
  73. 152 0
      modules/boonex/events/updates/13.0.3_13.0.4/source/install/config.php
  74. 51 0
      modules/boonex/files/updates/13.0.3_13.0.4/install/config.php
  75. 13 0
      modules/boonex/files/updates/13.0.3_13.0.4/install/installer.php
  76. 135 0
      modules/boonex/files/updates/13.0.3_13.0.4/source/install/config.php
  77. 17 0
      modules/boonex/files/updates/13.0.3_13.0.4/source/template/form_ghost_template.html
  78. 15 0
      modules/boonex/files/updates/13.0.3_13.0.4/source/template/form_ghost_template_upload.html
  79. 51 0
      modules/boonex/forum/updates/13.0.4_13.0.5/install/config.php
  80. 13 0
      modules/boonex/forum/updates/13.0.4_13.0.5/install/installer.php
  81. 227 0
      modules/boonex/forum/updates/13.0.4_13.0.5/source/classes/BxForumMenuCategories.php
  82. 263 0
      modules/boonex/forum/updates/13.0.4_13.0.5/source/classes/BxForumTemplate.php
  83. 149 0
      modules/boonex/forum/updates/13.0.4_13.0.5/source/install/config.php
  84. 581 0
      modules/boonex/forum/updates/13.0.4_13.0.5/source/template/css/main.css
  85. 30 0
      modules/boonex/forum/updates/13.0.4_13.0.5/source/template/unit_gallery.html
  86. 51 0
      modules/boonex/groups/updates/13.0.2_13.0.3/install/config.php
  87. 13 0
      modules/boonex/groups/updates/13.0.2_13.0.3/install/installer.php
  88. 152 0
      modules/boonex/groups/updates/13.0.2_13.0.3/source/install/config.php
  89. 50 0
      modules/boonex/groups/updates/13.0.2_13.0.3/source/js/invite_popup.js
  90. 51 0
      modules/boonex/invites/updates/13.0.1_13.0.2/install/config.php
  91. 13 0
      modules/boonex/invites/updates/13.0.1_13.0.2/install/installer.php
  92. 317 0
      modules/boonex/invites/updates/13.0.1_13.0.2/source/classes/BxInvGridRequests.php
  93. 566 0
      modules/boonex/invites/updates/13.0.1_13.0.2/source/classes/BxInvModule.php
  94. 80 0
      modules/boonex/invites/updates/13.0.1_13.0.2/source/install/config.php
  95. 51 0
      modules/boonex/lucid/updates/13.0.4_13.0.5/install/config.php
  96. 26 0
      modules/boonex/lucid/updates/13.0.4_13.0.5/install/installer.php
  97. 1343 0
      modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/css/default.less
  98. 5 0
      modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/designbox_10.html
  99. 5 0
      modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/designbox_13.html
  100. 5 0
      modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/designbox_3.html

+ 55 - 0
modules/boonex/ads/updates/13.0.3_13.0.4/install/config.php

@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Ads',
+    'version_from' => '13.0.3',
+    'version_to' => '13.0.4',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/ads/updates/update_13.0.3_13.0.4/',
+    'home_uri' => 'ads_update_1303_1304',
+
+    'module_dir' => 'boonex/ads/',
+    'module_uri' => 'ads',
+
+    'db_prefix' => 'bx_ads_',
+    'class_prefix' => 'BxAds',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Ads',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(
+        'template/form_ghost_template_cover.html',
+        'template/form_ghost_template_file.html',
+        'template/form_ghost_template_video.html'
+    ),
+);

+ 13 - 0
modules/boonex/ads/updates/13.0.3_13.0.4/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxAdsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 151 - 0
modules/boonex/ads/updates/13.0.3_13.0.4/source/install/config.php

@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Ads Ads
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_ads',
+    'title' => 'Ads',
+    'note' => 'Ads module.',
+    'version' => '13.0.4',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/ads/',
+    'home_uri' => 'ads',
+
+    'db_prefix' => 'bx_ads_',
+    'class_prefix' => 'BxAds',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Ads',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+    
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+    ),
+
+    /**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+        'bx_ads_covers',
+    	'bx_ads_photos',
+        'bx_ads_videos',
+        'bx_ads_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_ads_preview',
+        'bx_ads_gallery',
+        'bx_ads_cover',
+
+        'bx_ads_preview_photos',
+        'bx_ads_gallery_photos',
+        'bx_ads_view_photos',
+
+        'bx_ads_videos_poster',
+        'bx_ads_videos_poster_preview',
+        'bx_ads_videos_mp4',
+        'bx_ads_videos_mp4_hd',
+
+        'bx_ads_preview_files',
+        'bx_ads_gallery_files'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_ads',
+    	'bx_ads_cmts'
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+        'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+        'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+
+);
+
+/** @} */

+ 26 - 0
modules/boonex/ads/updates/13.0.3_13.0.4/source/template/form_ghost_template.html

@@ -0,0 +1,26 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost flex items-start mt-2">
+    <input type="hidden" name="__name__[]" value="{file_id}" />
+    <div class="bx-base-general-icon-wrapper mr-2">
+        <img src="{file_icon}" class="bx-base-general-icon rounded bx-base-general-icon-{file_id}" />
+    </div>
+    <span class="bx-base-general-uploader-ghost">
+        <div class="font-bold"><bx_text:_sys_txt_form_entry_input_picture_pic_url /></div>
+        <div class="bx-form-input-wrapper bx-form-input-wrapper-text mt-1">
+            <input class="bx-def-font-inputs bx-form-input-text" type="text" value="{file_url}" readonly="1" />
+        </div>
+        <div class="mt-2">
+            <span id="bx-base-general-intert-to-post-link-{file_id}" class="inline-block" style="display:none;">
+                <a class="bx-btn bx-btn-small mr-2" href="javascript:void(0);" onclick="bx_base_general_insert_to_post('{file_id}', '{file_url}', '__editor_id__');"><bx_text:_sys_txt_form_entry_input_picture_insert /></a>
+            </span>
+            <a class="bx-btn bx-btn-small mr-2" href="javascript:void(0);" onclick="bx_base_general_delete_ghost('{file_id}', '{file_url}', '{file_icon}', ['__editor_id__'], {js_instance_name});"><bx_text:_sys_txt_form_entry_input_picture_delete /></a>
+        </div>
+    </span>
+</div>
+<script>
+    $('#bx-base-general-intert-to-post-link-{file_id}').show();
+
+    // disable images drag&drop, because resized images address can be reset after some time
+    $(".bx-base-general-icon-{file_id}").bind('dragstart', function(){
+        return false; 
+    });
+</script>

+ 51 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Albums',
+    'version_from' => '13.0.1',
+    'version_to' => '13.0.2',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/albums/updates/update_13.0.1_13.0.2/',
+    'home_uri' => 'albums_update_1301_1302',
+
+    'module_dir' => 'boonex/albums/',
+    'module_uri' => 'albums',
+
+    'db_prefix' => 'bx_albums_',
+    'class_prefix' => 'BxAlbums',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Albums',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxAlbumsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 143 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/source/install/config.php

@@ -0,0 +1,143 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_albums',
+    'title' => 'Albums',
+    'note' => 'Photos & videos',
+    'version' => '13.0.2',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/albums/',
+    'home_uri' => 'albums',
+
+    'db_prefix' => 'bx_albums_',
+    'class_prefix' => 'BxAlbums',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Albums',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_albums_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_albums_preview',
+        'bx_albums_browse',
+        'bx_albums_big',
+        'bx_albums_video_poster_browse',
+        'bx_albums_video_poster_preview',
+        'bx_albums_video_poster_big',
+        'bx_albums_video_mp4',
+        'bx_albums_video_mp4_hd',
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_albums',
+    	'bx_albums_media',
+    	'bx_albums_cmts',
+        'bx_albums_media_cmts'
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+
+);
+
+/** @} */

+ 25 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/source/template/form_ghost_template.html

@@ -0,0 +1,25 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost mt-2 flex items-start">
+    <a class="bx-anchor-invisible" name="album-media-{file_id}"></a>
+    <input type="hidden" name="__name__[]" value="{file_id}" />
+    <div class="bx-base-general-icon-wrapper mr-2">
+        <img src="{file_icon}" class="bx-def-round-corners bx-base-general-icon bx-base-general-icon-{file_id}" />
+    </div>
+    <span class="bx-base-general-uploader-ghost">
+        <div class="font-bold"><bx_text:_bx_albums_form_entry_file_title /></div>
+        <div class="bx-form-input-wrapper bx-form-input-wrapper-text mt-1">
+            <input class="bx-def-font-inputs bx-form-input-text block w-full py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-md shadow-sm bg-white dark:bg-gray-900 placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-2 focus:text-gray-900 dark:focus:text-gray-100 focus:ring-blue-500 focus:border-opacity-70 focus:ring-opacity-20 focus:border-blue-500 text-sm text-gray-700 dark:text-gray-300 appearance-none" type="text" value="{file_title_attr}" name="title-{file_id}" /> <br />
+        </div>
+        <div class="mt-2">
+            <a class="bx-btn bx-btn-small bx-def-margin-sec-right" href="javascript:void(0);" onclick="bx_base_general_delete_ghost('{file_id}', '{file_url}', '{file_icon}', ['__editor_id__'], {js_instance_name});"><bx_text:_sys_txt_form_entry_input_picture_delete /></a>
+            <bx_if:set_thumb>
+                <span class="bx-base-general-use-as-thumb">
+                    <input type="checkbox" name="__name_thumb__[]" value="{file_id}" onclick="bx_base_general_select_thumb(this)" id="__name_thumb__-{file_id}" /> 
+                    <label for="__name_thumb__-{file_id}"><bx_text:_sys_txt_form_entry_input_picture_use_as_thumb /></label>
+                </span>
+            </bx_if:set_thumb>
+        </div>
+    </span>
+</div>
+<script>
+    $('#bx-uploader-file-{storage_object}-{file_id} .bx-base-general-use-as-thumb input[value="__thumb_id__"]').attr('checked', true);
+</script>

+ 28 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit.html

@@ -0,0 +1,28 @@
+<div class="bx-base-text-unit bx-base-text-unit-ext bx-def-box bx-def-box-round-corners bx-def-color-bg-box mb-3 md:mb-4 lg:mb-6 text-left">
+    <div class="bx-albums-unit-text-cont px-4 pt-4 pb-2">
+        <div class="bx-base-text-unit-title">
+            <a class="text-lg lg:text-xl font-semibold text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white" href="__content_url__">__title__</a>
+        </div>
+        <bx_if:meta>
+            <div class="bx-base-text-unit-info mt-1 mb-2">
+                <div class="bx-base-general-unit-meta">__meta__</div>
+            </div>
+        </bx_if:meta>
+        <div class="bx-base-text-unit-summary bx-clearfix">__summary__</div> 
+    </div>
+    <div class="bx-albums-unit-images-cont px-1 pb-4">
+        <div class="bx-albums-unit-images">
+            <bx_repeat:browse>
+                <a class="bx-albums-unit-image" title="__title_attr__" href="__url__">
+                    <img alt="__title_attr__" src="__img_url__" />
+                    <bx_if:show_play>
+                        <div class="bx-albums-media-play rounded"><i class="sys-icon play"></i></div>
+                    </bx_if:show_play>
+                    <bx_if:show_duration>
+                        <div class="bx-albums-media-duration px-2 py-1 border rounded text-base">__duration__</div>
+                    </bx_if:show_duration>
+                </a>
+            </bx_repeat:browse>
+        </div> 
+    </div> 
+</div>

+ 17 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit_gallery.html

@@ -0,0 +1,17 @@
+<div class="bx-base-text-unit bx-base-text-unit-gallery bx-def-gal-unit-size p-2">
+    <div class="bx-base-text-unit-cnt bx-def-box bx-def-box-round-corners bx-def-color-bg-box mb-3 md:mb-4 lg:mb-6 text-left">
+        <div class="bx-albums-unit-images-cont">
+            <div class="bx-albums-unit-images">
+                <bx_repeat:browse><a class="bx-albums-unit-image" title="__title_attr__" href="__url__"><img alt="__title_attr__" src="__img_url__" /></a></bx_repeat:browse>
+            </div> 
+        </div>
+        <div class="bx-albums-unit-text-cont px-4 py-2 text-center">
+            <div class="bx-base-text-unit-title">
+                <a class="text-lg lg:text-xl font-semibold text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white" href="__content_url__">__title__</a>
+            </div>
+            <div class="bx-base-text-unit-info">
+                <bx_if:meta><div class="bx-base-general-unit-meta">__meta__</div></bx_if:meta>
+            </div>
+        </div>
+    </div>
+</div>

+ 24 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit_media.html

@@ -0,0 +1,24 @@
+<div class="__class__ bx-albums-media-wrapper sm:w-full md:w-1/2 lg:w-1/3 p-2 box-border">
+    <div class="bx-albums-media-cnt bx-def-box bx-def-box-round-corners bx-def-color-bg-box">
+        <div class="bx-albums-media-thumb bx-albums-unit-size h-48 rounded-tl-md rounded-tr-md overflow-hidden">
+            <bx_if:image>
+                <a href="__url__" title="__title_attr__">
+                    <img class="bx-albums-unit-size h-48" src="__url_img__" alt="__title_attr__" />
+                </a>
+            </bx_if:image>
+            <bx_if:video>
+                <a href="__url__" title="__title_attr__">
+                    <img class="bx-albums-unit-size h-48" src="__url_img__" alt="__title_attr__" />
+                    <div class="bx-albums-media-play rounded-md"><i class="sys-icon play"></i></div>
+                </a>
+                <bx_if:show_duration>
+                    <div class="bx-albums-media-duration px-2 py-1 border text-sm rounded-md">__duration__</div>
+                </bx_if:show_duration>
+            </bx_if:video>
+        </div>
+        <div class="bx-albums-media-caption m-2">
+            <a href="__url__" title="__title_attr__">__title__</a>
+        </div>
+        <div class="bx-albums-media-actions mx-2 mb-2">__actions__</div>
+    </div>
+</div>

+ 23 - 0
modules/boonex/albums/updates/13.0.1_13.0.2/source/template/unit_media_gallery.html

@@ -0,0 +1,23 @@
+<div class="__class__ bx-albums-media-wrapper sm:w-full md:w-1/2 lg:w-1/3 p-2 box-border">
+    <div class="bx-albums-media-cnt bx-def-box bx-def-box-round-corners bx-def-color-bg-box">
+        <div class="bx-albums-media-thumb bx-albums-unit-size h-48 rounded-tl-md rounded-tr-md overflow-hidden">
+            <bx_if:image>
+                <a href="__url__" title="__title_attr__">
+                    <img class="bx-albums-unit-size h-48" src="__url_img__" alt="__title_attr__" />
+                </a>
+            </bx_if:image>
+            <bx_if:video>
+                <a href="__url__" title="__title_attr__">
+                    <img class="bx-albums-unit-size h-48" src="__url_img__" alt="__title_attr__" />
+                    <div class="bx-albums-media-play rounded-md"><i class="sys-icon play"></i></div>
+                </a>
+                <bx_if:show_duration>
+                    <div class="bx-albums-media-duration px-2 py-1 border text-sm rounded-md">__duration__</div>
+                </bx_if:show_duration>
+            </bx_if:video>
+        </div>
+        <div class="bx-albums-media-caption m-2">
+            <a href="__url__" title="__title_attr__">__title__</a>
+        </div>
+    </div>
+</div>

+ 137 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/install/config.php

@@ -0,0 +1,137 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Artificer',
+    'version_from' => '13.0.4',
+    'version_to' => '13.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/artificer/updates/update_13.0.4_13.0.5/',
+    'home_uri' => 'artificer_update_1304_1305',
+
+    'module_dir' => 'boonex/artificer/',
+    'module_uri' => 'artificer',
+
+    'db_prefix' => 'bx_artificer_',
+    'class_prefix' => 'BxArtificer',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Artificer Template',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(
+        'data/template/bx_albums/form_ghost_template.html', 
+        'data/template/bx_albums/unit.html', 
+        'data/template/bx_albums/unit_gallery.html', 
+        'data/template/bx_albums/unit_media.html', 
+        'data/template/bx_albums/unit_media_gallery.html', 
+        'data/template/bx_albums/', 
+        'data/template/bx_files/form_ghost_template.html', 
+        'data/template/bx_files/form_ghost_template_upload.html', 
+        'data/template/bx_market/form_ghost_template.html', 
+        'data/template/bx_market/form_ghost_template_file.html', 
+        'data/template/bx_market/unit_gallery.html', 
+        'data/template/bx_notifications/event.html', 
+        'data/template/bx_photos/form_ghost_template.html', 
+        'data/template/bx_photos/form_ghost_template_upload.html', 
+        'data/template/bx_photos/', 
+        'data/template/bx_timeline/block_async_outline.html', 
+        'data/template/bx_timeline/block_async_timeline.html', 
+        'data/template/bx_timeline/block_view.html', 
+        'data/template/bx_timeline/repost_element_block.html', 
+        'data/template/bx_timeline/type_post.html', 
+        'data/template/bx_videos/form_ghost_template.html', 
+        'data/template/bx_videos/form_ghost_template_video.html', 
+        'data/template/bx_videos/', 
+        'data/template/system/css/cmts.css', 
+        'data/template/system/css/connection.css', 
+        'data/template/system/css/favorite.css', 
+        'data/template/system/css/feature.css', 
+        'data/template/system/css/score.css', 
+        'data/template/system/css/view.css', 
+        'data/template/system/css/vote.css', 
+        'data/template/system/comment.html', 
+        'data/template/system/comments_controls.html', 
+        'data/template/system/comments_uploader_nfw.html', 
+        'data/template/system/comment_actions.html', 
+        'data/template/system/comment_attachments.html', 
+        'data/template/system/comment_counter.html', 
+        'data/template/system/comment_element_block.html', 
+        'data/template/system/comment_element_inline.html', 
+        'data/template/system/comment_reply_box.html', 
+        'data/template/system/comment_reply_to.html', 
+        'data/template/system/connected_by_list.html', 
+        'data/template/system/connection_counter.html', 
+        'data/template/system/connection_counter_label.html', 
+        'data/template/system/designbox_menu_popup.html', 
+        'data/template/system/designbox_share_popup.html', 
+        'data/template/system/favorite_element_block.html', 
+        'data/template/system/favorite_element_inline.html', 
+        'data/template/system/feature_element_block.html', 
+        'data/template/system/feature_element_inline.html', 
+        'data/template/system/form_field_price.html', 
+        'data/template/system/form_field_privacy.html', 
+        'data/template/system/menu_buttons_hor.html', 
+        'data/template/system/menu_buttons_icon_hor.html', 
+        'data/template/system/menu_custom_hor.html', 
+        'data/template/system/menu_item_addon.html', 
+        'data/template/system/menu_item_addon_middle.html', 
+        'data/template/system/menu_item_addon_small.html', 
+        'data/template/system/menu_item_more_popup.html', 
+        'data/template/system/menu_loading.html', 
+        'data/template/system/messageBox.html', 
+        'data/template/system/popup_content_indent.html', 
+        'data/template/system/popup_loading.html', 
+        'data/template/system/popup_trans.html', 
+        'data/template/system/profile_membership_stats.html', 
+        'data/template/system/report_element_block.html', 
+        'data/template/system/report_element_inline.html', 
+        'data/template/system/review_mood_form_field.html', 
+        'data/template/system/review_mood_legend.html', 
+        'data/template/system/score_counter.html', 
+        'data/template/system/score_counter_label.html', 
+        'data/template/system/score_element_block.html', 
+        'data/template/system/uploader_form_crop.html', 
+        'data/template/system/view_by_list.html', 
+        'data/template/system/view_counter.html', 
+        'data/template/system/view_counter_label.html', 
+        'data/template/system/view_element_block.html', 
+        'data/template/system/view_element_inline.html', 
+        'data/template/system/vote_counter.html', 
+        'data/template/system/vote_counter_label_likes.html', 
+        'data/template/system/vote_counter_label_reactions.html', 
+        'data/template/system/vote_counter_wrapper_reactions.html', 
+        'data/template/system/vote_do_vote_stars.html', 
+        'data/template/system/vote_element_block.html', 
+        'data/template/system/vote_element_inline.html', 
+        'data/template/system/vote_legend.html'
+    ),
+);

+ 26 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/install/installer.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxArtificerUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function update($aParams)
+    {
+        $aResult = parent::update($aParams);
+        if(!$aResult['result'])
+            return $aResult;
+
+        $oCacheUtilities = BxDolCacheUtilities::getInstance();
+        $oCacheUtilities->clear('css');
+        $oCacheUtilities->clear('template');
+
+        return $aResult;
+    }
+}

+ 5 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/install/langs/en.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string_add name="_bx_artificer_stg_cpt_option_images_custom"><![CDATA[Custom Images]]></string_add>
+    <string_add name="_bx_artificer_stg_cpt_option_images_custom_inf"><![CDATA[Each line represents an image. Line format: <b>name</b> => <b>value</b> => <b>type</b> => <b>class</b><br />Where <b>type</b> and/or <b>class</b> may be omitted. Available types are <b>ic</b> - icon (Font Awesome), <b>im</b> - image (file name or URL), <b>sc</b> - source code (SVG).]]></string_add>
+</resources>

+ 9 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/install/sql/enable.sql

@@ -0,0 +1,9 @@
+SET @sName = 'bx_artificer';
+
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name`=@sName LIMIT 1);
+
+DELETE FROM `sys_alerts` WHERE `unit`='system' AND `action`='get_layout_images' AND `handler_id`=@iHandler;
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'get_layout_images', @iHandler);

+ 7 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/install/sql/install.sql

@@ -0,0 +1,7 @@
+SET @sName = 'bx_artificer';
+
+SET @iCategoryId = (SELECT `id` FROM `sys_options_categories` WHERE `name`='bx_artificer_styles_custom' LIMIT 1);
+
+DELETE FROM `sys_options` WHERE `name`=CONCAT(@sName, '_images_custom');
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, CONCAT(@sName, '_images_custom'), '_bx_artificer_stg_cpt_option_images_custom', '', 'text', '', '', '', 10);

+ 142 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/classes/BxArtificerAlertsResponse.php

@@ -0,0 +1,142 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Artificer Artificer template
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+
+class BxArtificerAlertsResponse extends BxBaseModTemplateAlertsResponse
+{
+    public function __construct()
+    {
+        $this->_sModule = 'bx_artificer';
+
+        parent::__construct();
+    }
+
+    protected function _processSystemChangeLogo($oAlert)
+    {
+        $sPrefix = $this->_oModule->_oConfig->getPrefix('option');
+
+        if(!in_array($oAlert->aExtras['option'], ['sys_site_logo', $sPrefix . 'site_logo']))
+            return;
+
+        setParam($sPrefix . 'site_logo_aspect_ratio', '');
+    }
+
+    protected function _processSystemChangeMark($oAlert)
+    {
+        $sPrefix = $this->_oModule->_oConfig->getPrefix('option');
+
+        if(!in_array($oAlert->aExtras['option'], ['sys_site_mark', $sPrefix . 'site_mark']))
+            return;
+
+        setParam($sPrefix . 'site_mark_aspect_ratio', '');
+    }
+
+    protected function _processSystemGetObject($oAlert)
+    {
+        if(!$this->_isActive())
+            return;
+
+        if(empty($oAlert->aExtras['type']))
+            return;
+
+        switch($oAlert->aExtras['type']) {
+            case 'menu':
+                if(!($oAlert->aExtras['object'] instanceof BxBaseModGeneralMenuViewActions))
+                    break;
+
+                $oAlert->aExtras['object']->setShowAsButton(false);
+                break;
+        }
+    }
+
+    protected function _processSystemGetLayoutImages($oAlert)
+    {
+        $sImages = getParam($this->_oModule->_oConfig->getPrefix('option') . 'images_custom');
+        if(!$sImages)
+            return;
+        
+        $aImages = preg_split("/\\r\\n|\\r|\\n/", $sImages);
+        if(empty($aImages) || !is_array($aImages))
+            return;
+
+        foreach($aImages as $sImage) {
+            $aImage = explode('=>', $sImage);
+            if(empty($aImage))
+                continue;
+
+            switch(count($aImage)) {
+                case 2:
+                    list($sName, $sValue) = $aImage;
+
+                    $aCacheItemKeys = ['v'];
+                    $aCacheItemValues = [$sValue];
+                    break;
+
+                case 3:
+                    list($sName, $sValue, $sType) = $aImage;
+
+                    $aCacheItemKeys = ['v', 't'];
+                    $aCacheItemValues = [$sValue, $sType];
+                    break;
+
+                case 4:
+                    list($sName, $sValue, $sType, $sClass) = $aImage;
+
+                    $aCacheItemKeys = ['v', 't', 'c'];
+                    $aCacheItemValues = [$sValue, $sType, $sClass];
+                    break;
+
+                default:
+                    continue 2;
+            }
+
+            $sCacheItemKey = md5(trim($sName));
+            if(!isset($oAlert->aExtras['override_result'][$sCacheItemKey]))
+                continue;
+            
+            foreach($aCacheItemValues as $i => $s)
+                $aCacheItemValues[$i] = trim($s);
+
+            $aCacheItem = array_combine($aCacheItemKeys, $aCacheItemValues);
+
+            if(isset($aCacheItem['t']) && $aCacheItem['t'] == 'im')
+                foreach(['Image', 'Icon'] as $sUrlType) 
+                    if(($sUrl = $this->_oModule->_oTemplate->{'get' . $sUrlType . 'Url'}($aCacheItem['v'])) != '')
+                        $aCacheItem['v'] = $sUrl;
+
+            $oAlert->aExtras['override_result'][$sCacheItemKey] = array_merge($oAlert->aExtras['override_result'][$sCacheItemKey], $aCacheItem);
+        }
+    }
+
+    protected function _processProfileUnit($oAlert)
+    {
+        if(!$this->_isActive())
+            return;
+
+        $sModule = $oAlert->aExtras['module'];
+        $oModule = BxDolModule::getInstance($sModule);
+        if(!$oModule)
+            return;
+
+        $sTemplate = !empty($oAlert->aExtras['template']) && is_array($oAlert->aExtras['template']) ? $oAlert->aExtras['template'][0] : $oAlert->aExtras['template'];
+        $sClassSize = $this->_oModule->_oConfig->getThumbSize(isset($oAlert->aExtras['template'][1]) ? $oAlert->aExtras['template'][1] : '', $sTemplate);
+
+        $aTmplVars['class_size'] = $sClassSize;
+        $aTmplVars['bx_if:show_thumb_letter']['content']['class_size'] = $sClassSize;
+        $aTmplVars['bx_if:show_thumb_image']['content']['class_size'] = $sClassSize;
+        
+        $aTmplVars['bx_if:show_thumbnail']['content']['class_size'] = $sClassSize;
+        $aTmplVars['bx_if:show_thumbnail']['content']['bx_if:show_thumb_letter']['content']['class_size'] = $sClassSize;
+        $aTmplVars['bx_if:show_thumbnail']['content']['bx_if:show_thumb_image']['content']['class_size'] = $sClassSize;
+    }
+}
+
+/** @} */

+ 43 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/classes/BxArtificerStudioOptions.php

@@ -0,0 +1,43 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Artificer Artificer template
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxArtificerStudioOptions extends BxTemplStudioOptions
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    public function __construct($sType = '', $sCategory = '', $sMix = '')
+    {
+        parent::__construct($sType, $sCategory, $sMix);
+
+        $this->_sModule = 'bx_artificer';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+    }
+
+    protected function field($aItem, $aItems2Mixes)
+    {
+        $sPrefix = $this->_oModule->_oConfig->getPrefix('option');
+
+        $aField = parent::field($aItem, $aItems2Mixes);
+
+        switch($aItem['name']) {
+            case $sPrefix . 'images_custom':
+                $aField = array_merge($aField, [
+                    'info' => _t('_bx_artificer_stg_cpt_option_images_custom_inf'),
+                    'code' => 1
+                ]);
+                break;
+        }
+
+        return $aField;
+    }
+}
+/** @} */

+ 54 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/classes/BxArtificerStudioPage.php

@@ -0,0 +1,54 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Artificer Artificer template
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once('BxArtificerStudioOptions.php');
+
+define('BX_ARTIFICER_STUDIO_TEMPL_TYPE_STYLES', 'styles');
+
+class BxArtificerStudioPage extends BxTemplStudioDesign
+{
+    function __construct($sModule, $mixedPageName, $sPage = "")
+    {
+        parent::__construct($sModule, $mixedPageName, $sPage);
+
+        $this->aMenuItems = bx_array_insert_after([
+            BX_ARTIFICER_STUDIO_TEMPL_TYPE_STYLES => ['title' => '_bx_artificer_lmi_cpt_styles', 'icon' => 'paint-brush']
+        ], $this->aMenuItems, BX_DOL_STUDIO_TEMPL_TYPE_SETTINGS);
+    }
+
+    protected function getSettings($mixedCategory = '', $sMix = '')
+    {
+    	return parent::getSettings('bx_artificer_system', $sMix);
+    }
+
+    protected function getStyles($mixedCategory = '', $sMix = '')
+    {
+    	$sPrefix = $this->sModule;
+
+        if(empty($mixedCategory))
+            $mixedCategory = [
+                $sPrefix . '_styles_custom',
+            ];
+
+    	$oOptions = new BxArtificerStudioOptions($this->sModule, $mixedCategory, $sMix);
+
+        $this->aPageCss = array_merge($this->aPageCss, $oOptions->getCss(), [BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'codemirror/|codemirror.css']);
+        $this->aPageJs = array_merge($this->aPageJs, $oOptions->getJs(), ['codemirror/codemirror.min.js']);
+        return BxDolStudioTemplate::getInstance()->parseHtmlByName('design.html', [
+            'content' => $oOptions->getCode(),
+            'js_content' => $this->getPageJsCode([
+                'sCodeMirror' => "textarea[name='" . $sPrefix . "_styles_custom'],textarea[name='" . $sPrefix . "_images_custom']"
+            ])
+        ]);
+    }
+}
+
+/** @} */

+ 102 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_forum/css/main.css

@@ -0,0 +1,102 @@
+@import url(../../../../../forum/template/css/main.css);
+
+/*-- Participants --*/
+div.bx-forum-participants.left,
+div.bx-forum-participants.none,
+div.bx-forum-participants.right {
+    float: none;
+}
+div.bx-forum-participants.left {
+    -webkit-justify-content: flex-start;
+    justify-content: flex-start;
+}
+div.bx-forum-participants.right {
+    -webkit-flex-direction: row-reverse;
+    flex-direction: row-reverse;
+}
+div.bx-forum-participants .bx-forum-participant {
+    float: none;
+}
+div.bx-forum-participants.left .bx-forum-participant,
+div.bx-forum-participants.none .bx-forum-participant {
+    float: none;
+    margin-right: 0.75rem;
+}
+.bx-forum-participants.right .bx-forum-participant {
+    float: none;
+    margin-left: 0.75rem;
+}
+.bx-forum-participant .bx-forum-participant-alert-last-replier {
+    left: -0.375rem;
+    right: auto;
+    top: -0.375rem;
+    bottom: auto;
+}
+.bx-forum-participant .bx-forum-participant-alert-author {
+    left: -0.375rem;
+    right: auto;
+    top: auto;
+    bottom: -0.375rem;
+}
+
+
+/*-- Grid: Preview --*/
+.bx-forum-grid-preview .bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li a {
+    display: -webkit-flex;
+    display: flex;
+}
+
+/* forum units - new view, for UNA14 need to migrate in general */
+.bx-base-unit-showcase-wrapper.bx-forum-wrapper{
+    white-space:normal;
+    text-align: left !important;
+}
+.bx-base-unit-showcase-wrapper.bx-forum-wrapper:not(.flickity-enabled) .bx-base-text-unit-showcase{
+    width: 100%
+}
+
+.bx-media-desktop .bx-layout-column-half .bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .bx-base-text-unit-showcase,
+.bx-media-desktop .bx-layout-column-wide .bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .bx-base-text-unit-showcase {
+    width:calc(33%);
+}
+
+.bx-media-desktop #sys_search_results  .bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .bx-base-text-unit-showcase,
+.bx-media-desktop .bx-layout-column-fullwidth  .bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .bx-base-text-unit-showcase {
+    width:calc(25%);
+}
+.bx-artificer .bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .flickity-slider .bx-base-text-unit-showcase > div {
+    margin-left: 0.5rem !important;
+    margin-right: 0.5rem !important;
+}
+
+.bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper{
+    margin-left: -0.5rem;
+    margin-right: -0.5rem;
+}
+
+.bx-artificer .bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .flickity-slider .bx-base-text-unit-showcase{
+    margin-left: 0px !important;
+    margin-right: 0rem !important;
+}
+.bx-base-unit-showcase-wrapper.flickity-enabled.bx-forum-wrapper .bx-base-text-unit-showcase{
+    padding-left: 0px !important;
+    padding-right: 0px !important;
+}
+#bx-forum-snippet-meta-main{
+    margin-left: 0px;
+}
+.bx-menu-meta-item-ex {
+    margin-right: 0px !important;
+}
+.bx-menu-meta-item-ex span:nth-child(2){
+    margin-left: 0.375rem;
+}
+.bx-menu-meta-item-ex .bx-menu-meta-icon{
+    min-width: 16px;
+    text-align: center;
+}
+
+.bx-base-unit-showcase-wrapper.bx-forum-wrapper{
+    display: flex;
+    flex-wrap: nowrap;
+}

+ 1 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_forum/score_do_vote_label.html

@@ -0,0 +1 @@
+<span class="sys-action-do __style_prefix__-do bx-def-valign-center group text-gray-700 dark:text-gray-300 hover:text-gray-800 dark:hover:text-white"><bx_if:show_icon><span class="sys-action-do-icon __style_prefix__-do-icon bx-def-align-center">__icon__</span></bx_if:show_icon><bx_if:show_text><span class="sys-action-do-text __style_prefix__-do-text bx-def-margin-sec-left-auto">__text__</span></bx_if:show_text></span>

+ 4 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_polls/css/main.css

@@ -0,0 +1,4 @@
+/*-- View page --*/
+.bx-content-description-after .bx-vote-counter-wrapper {
+    padding-top: 1rem;
+}

+ 351 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/css/view.css

@@ -0,0 +1,351 @@
+/*--
+import url(../../../../../timeline/template/css/view.css);
+--*/
+
+/*--- Dynamic Browsing: Menu ---*/
+.bx-tl-menu-feeds.bx-menu-ver li img, 
+.bx-tl-menu-feeds.bx-menu-ver li .sys-icon {
+    display: inline-block;
+    vertical-align: top;
+    width: 1.5rem;
+    height: 1.5rem;
+
+    background-size: 1.25rem 1.25rem;
+    background-position: center center;
+
+    line-height: 1.5rem;
+    font-size: 1.0rem;
+}
+.bx-tl-menu-feeds.bx-menu-ver li .bx-menu-show {
+    display: none;
+}
+.bx-tl-menu-feeds.bx-menu-ver li .bx-menu-hide {
+    display: inline;
+}
+.bx-tl-menu-feeds.bx-menu-ver li.bx-mi-collapsed .bx-menu-show {
+    display: inline;
+}
+.bx-tl-menu-feeds.bx-menu-ver li.bx-mi-collapsed .bx-menu-hide {
+    display: none;
+}
+.bx-tl-menu-feeds.bx-menu-ver li.bx-mi-collapsed .bx-menu-item-subitems {
+    display: none;
+}
+
+/*--- Filters Style ---*/
+div.bx-tl-view-filters {
+    min-width: 14rem;
+    max-width: 20rem;
+}
+div.bx-tl-view-filters div.bx-form-section-wrapper:first-child {
+    margin-top: 0;
+}
+div.bx-tl-view-filters div.bx-form-section-content {
+    padding-top: 0;
+    padding-bottom: 0;
+}
+
+/*--- Load More Style ---*/
+div.bx-tl-view-timeline div.bx-tl-load-more {
+    padding-top: 0px;
+}
+
+/*--- Item Style: Timeline ---*/
+div.bx-tl-view-timeline div.bx-tl-items,
+div.bx-tl-view-search div.bx-tl-items,
+div.bx-tl-view-item div.bx-tl-items {
+    margin-left: 0px;
+    margin-right: 0px;
+}
+
+/*--- Item Meta Info Style ---*/
+.bx-tl-item-meta ul.bx-menu-custom li:first-child .bx-tl-item-meta-div {
+    display: none;
+}
+
+/*--- Item Content Style ---*/
+div.bx-tl-item-content form {
+    padding: 1rem 1rem 0 1rem;
+}
+
+div.bx-tl-item-text div.bx-tl-content {
+    position: relative;
+    max-height: 16rem;
+}
+div.bx-tl-item-text div.bx-tl-content.bx-tl-overflow {
+    margin-bottom: 0;
+}
+div.bx-tl-item-text div.bx-tl-content.bx-tl-overflow:before {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    height: 20%;
+
+    content: '';
+}
+
+/*--- Item Activity (Actions and Manage are different menus) ---*/
+div.bx-tl-item div.bx-tl-item-activity .bx-menu-custom.bx-menu-custom-hor {
+    flex-wrap: wrap;
+}
+div.bx-tl-item div.bx-tl-item-activity.bx-tl-ia-counters .bx-menu-custom.bx-menu-custom-hor li > a,
+div.bx-tl-item div.bx-tl-item-activity.bx-tl-ia-counters .bx-menu-custom.bx-menu-custom-hor li > div,
+div.bx-tl-item div.bx-tl-item-activity.bx-tl-ia-counters .bx-menu-custom.bx-menu-custom-hor li > span {
+    display: block;
+    margin-top: 1.0rem;
+}
+
+.bx-menu-object-bx_timeline_menu_item_manage .menu-custom-item-ver a,
+.bx-menu-object-bx_timeline_menu_item_manage .bx-report-element-holder a {
+    display: block;
+    width: 100%;
+    box-sizing: border-box;
+}
+.bx-menu-object-bx_timeline_menu_item_manage .bx-report-element-holder {
+    -webkit-flex: 1 0 auto;
+    flex: 1 0 auto;
+
+    padding: 0px !important;
+}
+.bx-menu-object-bx_timeline_menu_item_manage .bx-report-counter-holder {
+    -webkit-flex: 0 1 auto;
+    flex: 0 1 auto;
+
+    padding-right: 1rem;
+}
+.bx-tl-owner-avatar .bx-def-thumb-size{
+    width: 2.5rem;
+    height: 2.5rem;
+}
+.bx-tl-item-content video,
+.bx-tl-item-attachment img{
+    border-radius: .25rem;
+}
+
+/*--- Menu: Item Manage ---*/
+.bx-menu-object-bx_timeline_menu_item_manage .sys-action-do-text {
+    margin-left: 0rem;
+}
+
+/*--- Item Action Style ---*/
+div.bx-tl-item div.bx-tl-item-action .bx-tl-timeline-owner-name .bx-tl-ton-div:first-child {
+    display: none;
+}
+
+/*+++ Item Text +++*/
+div.bx-tl-view-outline div.bx-tl-item-text div.bx-tl-title {
+    font-weight: bold;
+}
+div.bx-tl-view-outline div.bx-tl-content-show-more a {
+    font-weight: bold;
+}
+
+/*+++ Item Image +++*/
+div.bx-tl-view-search div.bx-tl-item-images {
+    margin-left: 0px;
+    margin-right: 0px;
+}
+div.bx-tl-view-search div.bx-tl-item-image {
+    margin-right: 2px;
+    margin-right: 0.125rem;
+}
+div.bx-tl-view-timeline div.bx-tl-item-image,
+div.bx-tl-view-outline div.bx-tl-item-image,
+div.bx-tl-view-item div.bx-tl-item-image {
+    width: 100%;
+    text-align: center;
+    overflow: hidden;
+}
+div.bx-tl-view-search div.bx-tl-item-image img {
+    height: 12.5rem;
+}
+div.bx-tl-view-timeline div.bx-tl-item-images.bx-tl-ii-gallery div.bx-tl-item-image img,
+div.bx-tl-view-item div.bx-tl-item-images.bx-tl-ii-gallery div.bx-tl-item-image img,
+div.bx-tl-view-timeline div.bx-tl-item-images.bx-tl-ii-single div.bx-tl-item-image img,
+div.bx-tl-view-item  div.bx-tl-item-images.bx-tl-ii-single div.bx-tl-item-image img {
+    position: relative;
+    display: block;
+    max-width: 100%;
+    margin-left: auto;
+    margin-right: auto;
+}
+div.bx-tl-view-outline div.bx-tl-item-image img {
+    max-width: 100%;
+    object-fit: cover;
+    object-position: center center;
+}
+
+/*+++ Item Video +++*/
+div.bx-tl-view-timeline div.bx-tl-item-video,
+div.bx-tl-view-outline div.bx-tl-item-video,
+div.bx-tl-view-item div.bx-tl-item-video {
+    width: 100%;
+}
+.bx-tl-video-iframe {
+    width: 100%;
+    border: none;
+}
+div.bx-tl-view div.bx-tl-item-videos.bx-tl-iv-gallery div.bx-tl-item-video video,
+div.bx-tl-view div.bx-tl-item-videos.bx-tl-iv-single div.bx-tl-item-video video {
+    display: block;
+    max-width: 100%;
+    margin-left: auto;
+    margin-right: auto;
+}
+
+/*+++ Item Attachment +++*/
+div.bx-tl-view div.bx-tl-item-attachments {
+    position: relative;
+    white-space: nowrap;
+    overflow-x: auto;
+}
+div.bx-tl-view div.bx-tl-item-attachments div.bx-tl-item-attachment {
+    position: relative;
+    display: -webkit-inline-flex;
+    display: inline-flex;
+    -webkit-justify-content: center;
+    justify-content: center;  
+
+    width: 100%;
+    vertical-align: middle;
+}
+div.bx-tl-view div.bx-tl-item-attachments div.bx-tl-item-attachment img {
+    position: relative;
+    display: block;
+    max-width: 100%;
+    margin-left: auto;
+    margin-right: auto;
+}
+div.bx-tl-view-outline div.bx-tl-item-attachment img {
+    max-width: 100%;
+    object-fit: cover;
+    object-position: center center;
+}
+
+/*+++ Video +++*/
+div.bx-tl-view-timeline div.bx-tl-item-attachment video,
+div.bx-tl-view-outline div.bx-tl-item-attachment video,
+div.bx-tl-view-item div.bx-tl-item-attachment video {
+    display: block;
+    max-width: 100%;
+    margin-left: auto;
+    margin-right: auto;
+}
+div.bx-tl-item-attachment .bx-tl-item-video {
+    position: relative;
+}
+div.bx-tl-item-attachment .bx-tl-iv-duration {
+    position: absolute;
+    right: 0.25rem;
+    bottom: 0.25rem;
+    background-color: rgba(255, 255, 255, 0.8);
+}
+
+
+/*+++ Showcase Layout +++*/
+div.bx-tl-view div.bx-tl-item-attachments.bx-tl-ia-showcase {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+    -webkit-justify-content: space-between;
+    justify-content: space-between;
+}
+div.bx-tl-view div.bx-tl-item-attachments.bx-tl-ia-showcase div.bx-tl-item-attachment {
+    box-sizing: border-box;
+    width: 33.2%;
+    height: 8.5rem;
+    border: 1px solid transparent;
+}
+div.bx-tl-view div.bx-tl-item-attachments.bx-tl-ia-showcase div.bx-tl-item-attachment.bx-tl-ia-first,
+div.bx-tl-view div.bx-tl-item-attachments.bx-tl-ia-showcase.bx-tl-ia-i2 div.bx-tl-item-attachment {
+    width: 100%;
+    height: auto;
+}
+div.bx-tl-view div.bx-tl-item-attachments.bx-tl-ia-showcase.bx-tl-ia-i3 div.bx-tl-item-attachment:not(.bx-tl-ia-first) {
+    width: 50%;
+}
+div.bx-tl-item-attachments.bx-tl-ia-showcase a,
+div.bx-tl-item-attachments.bx-tl-ia-showcase img {
+    position: relative;
+    display: block;
+    width: 100%;
+    height: 100%;
+}
+div.bx-tl-item-attachments.bx-tl-ia-showcase img {
+    object-fit: cover;
+}
+div.bx-tl-item-attachments.bx-tl-ia-showcase .bx-tl-item-more {
+    position: absolute;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    justify-content: center;
+
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.7);
+
+    font-size: 2.5rem;
+}
+div.bx-tl-item-attachments.bx-tl-ia-showcase .bx-tl-item-more,
+div.bx-tl-item-attachments.bx-tl-ia-showcase .bx-tl-item-more a {
+    color: #ffffff;
+}
+
+
+/*+++ Slider Styles  +++*/
+div.bx-tl-item-images .flickity-slider,
+div.bx-tl-item-videos .flickity-slider,
+div.bx-tl-item-attachments .flickity-slider {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+}
+
+/*+++ Item Link +++*/
+div.bx-tl-view-outline div.bx-tl-item-link {
+    text-align: center;
+}
+div.bx-tl-view-outline div.bx-tl-il-thumbnail img {
+    width: 100%;
+    max-width: 100px;
+    height: 100%;
+    max-height: 100px;
+}
+div.bx-tl-view-outline div.bx-tl-il-embed iframe,
+div.bx-tl-view-timeline div.bx-tl-il-embed iframe {
+    width: 100%;
+}
+
+/*--- Item Brief Style ---*/
+div.bx-tl-bview-images {
+    position: relative;
+}
+div.bx-tl-bview-image.bx-tl-bvi-single,
+div.bx-tl-bview-images div.bx-tl-bview-image {
+    width: 100%;
+    height: calc(100vh - 7rem);
+    text-align: center;
+}
+div.bx-tl-bview-image.bx-tl-bvi-single img,
+div.bx-tl-bview-images div.bx-tl-bview-image:not(.bx-tl-bvi-single) img {
+    position: relative;
+    max-width: 100% !important;
+    max-height: 100% !important;
+    margin-left: auto;
+    margin-right: auto;
+}
+div.bx-tl-bview-image.bx-tl-bvi-single {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    justify-content: center;
+}

+ 5 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_hor_bx_timeline_menu_item_actions.html

@@ -0,0 +1,5 @@
+<ul id="__html_id__" class="bx-menu-custom bx-menu-custom-hor bx-menu-hor-inline<bx_if:show_more_auto_class> bx-menu-more-auto</bx_if:show_more_auto_class> bx-menu-object-__object__ flex justify-start items-start space-x-2">
+    <bx_repeat:menu_items>
+        <li class="bx-menu-item bx-menu-item-__name____class__ bx-stl-mil-wo-gaps-sm group">__item__</li>
+    </bx_repeat:menu_items>
+</ul>__js_code__

+ 13 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_item_hor.html

@@ -0,0 +1,13 @@
+<span class="__class_wrp__ menu-custom-item-hor mci-action">
+    <a class="__class_link__ bx-stl-mil-gaps-sm flex items-center" href="__link__" onclick="__onclick__" title="__title_attr__"__attrs__>
+        <span class="flex items-center">
+            <span class="bx-menu-item-icon bx-stl-mii-sm group-hover:text-gray-700 dark:group-hover:text-gray-300">
+                <bx_include_auto:menu_icon.html />
+            </span>
+            <bx_if:title>
+                <span class="bx-menu-item-title bx-stl-mit">__title__</span>
+            </bx_if:title>
+        </span>
+    </a>
+    <bx_if:addon>__addon__</bx_if:addon>
+</span>

+ 11 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_item_ver.html

@@ -0,0 +1,11 @@
+<span class="__class_wrp__ menu-custom-item-ver mci-manage">
+    <a class="__class_link__ bx-stl-mil-gaps-sm flex items-center space-x-1" href="__link__" onclick="__onclick__" title="__title_attr__"__attrs__>
+        <span class="flex items-center">
+            <span class="bx-menu-item-icon bx-stl-mii-sm group-hover:text-gray-700 dark:group-hover:text-gray-300">
+                <bx_include_auto:menu_icon.html />
+            </span>
+            <bx_if:title><span class="bx-menu-item-title bx-stl-mit">__title__</span></bx_if:title>
+        </span>
+    </a>
+    <bx_if:addon>__addon__</bx_if:addon>
+</span>

+ 7 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_custom_ver_bx_timeline_menu_item_manage.html

@@ -0,0 +1,7 @@
+<div class="w-full md:w-56 box-border">
+    <ul class="bx-menu-custom bx-menu-custom-ver bx-menu-object-__object__ bx-clearfix">
+        <bx_repeat:menu_items>
+            <li class="bx-menu-item bx-menu-item-__name____class__ bx-stl-mil-wo-gaps-sm group">__item__</li>
+        </bx_repeat:menu_items>
+    </ul>
+</div>

+ 18 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/bx_timeline/menu_vertical_bx_timeline_menu_item_share.html

@@ -0,0 +1,18 @@
+<ul class="bx-menu-ver bx-menu-object-__object__ bx-clearfix">
+    <bx_repeat:menu_items>
+        <li class="bx-menu-item __name__ __class_add__ bx-stl-mil-wo-gaps-sm group">
+            <a class="__name__ bx-stl-mil-gaps-sm flex flex-2 items-center truncate" href="__link__" onclick="__onclick__" __attrs__>
+                <span class="bx-menu-item-icon bx-stl-mii-sm group-hover:text-gray-700 dark:group-hover:text-gray-300">
+                    <bx_include_auto:menu_icon.html />
+                </span>
+                <span class="bx-menu-item-title bx-stl-mit">__title__</span>
+            </a>
+        </li>
+    </bx_repeat:menu_items>
+</ul>
+<script language="javascript">
+    $(document).ready(function () {
+        // add default class to active menu items
+        $('.bx-menu-ver > li.bx-menu-tab-active').not('.bx-def-color-bg-active').addClass('bx-def-color-bg-active');
+    });
+</script>

+ 102 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_general/css/main.css

@@ -0,0 +1,102 @@
+/* attachments */
+.bx-base-general-attachments .bx-base-general-attachment video,
+.flickity-enabled .flickity-viewport .flickity-slider .bx-base-general-attachment video {
+    max-width:100%;
+    max-height:100%;
+}
+.bx-base-general-attachment a div {
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+.bx-base-general-attachment a canvas {
+    position:absolute;
+    top:0;
+    left:0;
+}
+
+.bx-base-general-attachment-sound {
+    position:relative;
+    height:100%;
+}
+.bx-base-general-attachment-sound-file-name,
+.bx-base-general-attachment-sound-player {
+  display: flex;
+  justify-content: center;
+  align-content: center;
+  flex-direction: column;
+}
+.bx-base-general-attachment-sound-file-name {
+    height:9.25rem;
+}
+.bx-base-general-attachment-sound-player {
+    height:3.25rem;
+}
+
+/* unit meta */
+.bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor {
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+}
+.bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor > li {
+    white-space: nowrap;
+}
+.bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor > li.bx-menu-item-nl {
+    display: none;
+    width: 100%;
+    height: 0;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor > li.bx-menu-item-nl {
+    display: block;
+}
+.bx-base-general-unit-meta ul.bx-menu-custom li:first-child .bx-base-general-unit-meta-div {
+    display: none;
+}
+.bx-base-general-unit-meta ul.bx-menu-custom li .bx-metatags-keyword {
+    margin: 0px;
+    line-height: normal;
+}
+
+/* Browsing by labels */
+.bx-base-general-lables-tree-parent-0, 
+.bx-base-general-lables-tree-parent-0 ul {
+    list-style-type: none;
+    padding-left: 2rem;
+}
+.bx-base-general-lables-tree-parent-0 {
+    margin: 0px;
+}
+.bx-base-general-lables-tree-parent-0 li {
+    padding: 0px;
+}
+.bx-base-general-lables-tree-parent-0 li i.sys-icon {
+    display: inline-block;
+    width: 0.625rem;
+    margin-left: -1rem;
+}
+.bx-badge-icon{
+    color:inherit;
+}
+
+/* more menu */
+.bx-menu-submenu-more-auto .bx-menu-item:not(.bx-stl-mil-wo-gaps-sm) .sys-action-do-icon,
+.bx-menu-submenu-more-auto .bx-menu-item:not(.bx-stl-mil-wo-gaps-sm) .bx-vote-do-icon,
+.bx-menu-submenu-more-auto .bx-menu-item:not(.bx-stl-mil-wo-gaps-sm) .bx-favorite-do-icon,
+.bx-menu-submenu-more-auto .bx-menu-item:not(.bx-stl-mil-wo-gaps-sm) .bx-feature-do-icon,
+.bx-menu-submenu-more-auto .bx-menu-item:not(.bx-stl-mil-wo-gaps-sm) .bx-report-do-icon,
+.bx-menu-submenu-more-auto .bx-menu-item:not(.bx-stl-mil-wo-gaps-sm) .bx-score-do-icon {
+    height: 1.25rem;
+    width: 1.25rem;
+    align-items: center;
+    justify-content: center;
+}
+.sys-action-counter-holder .bx-view-counter-label {
+    padding: 0px;
+}
+.bx-base-unit-showcase-wrapper {
+    display: block;
+    white-space: nowrap;
+    overflow: hidden;
+}
+.bx-base-unit-showcase-wrapper .bx-base-text-unit-showcase{
+    display: inline-block;
+}

+ 268 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_profile/css/main.css

@@ -0,0 +1,268 @@
+/*--- Units ---*/
+.bx-base-pofile-units-wrapper:not(.bx-base-unit-showcase-wrapper) {
+    display: -webkit-flex;
+    display: flex;
+
+    -webkit-align-items: stretch;
+    align-items: stretch;
+
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+
+    -webkit-justify-content: flex-start;
+    justify-content: flex-start;
+}
+
+.bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover {
+    -webkit-flex: 0 0 100%;
+    flex: 0 0 100%;
+
+    overflow: hidden;
+}
+.bx-base-unit-showcase-wrapper.bx-sc-enabled .bx-base-pofile-unit-with-cover {
+    height: 100%;
+}
+
+.bx-base-pofile-unit-with-cover .bx-base-pofile-unit-online {
+    right: 0.5rem;
+    bottom: 0.5rem;
+}
+.bx-base-pofile-cover-thumb .bx-base-pofile-unit-online {
+    width: 1rem;
+    height: 1rem;
+    right: 1.25rem;
+    bottom: 1.25rem;
+}
+
+/*--- Units: Showcase view ---*/
+.bx-base-unit-showcase-wrapper {
+    text-align: center;
+}
+
+.bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    display: inline-block;
+    vertical-align: top;
+}
+
+/*+++ MEDIA: tablet2 +++*/
+.bx-media-tablet2 .bx-layout-column-wide .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover,
+.bx-media-tablet2 #sys_search_results .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover,
+.bx-media-tablet2 .bx-layout-column-fullwidth .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover {
+    -webkit-flex: 0 0 49.8%;
+    -ms-flex: 0 0 49.8%;
+    flex: 0 0 49.8%;
+}
+
+.bx-media-tablet2 .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(50%);
+}
+.bx-media-tablet2 .bx-layout-column-thin .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(100%);
+}
+
+.bx-media-tablet2 .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(10.0%);
+}
+.bx-media-tablet2 .bx-layout-column-thin .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(16.6%);
+}
+
+/*+++ MEDIA: desktop +++*/
+.bx-media-desktop .bx-layout-column-wide .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover {
+    -webkit-flex: 0 0 49.8%;
+    -ms-flex: 0 0 49.8%;
+    flex: 0 0 49.8%;
+}
+.bx-media-desktop #sys_search_results .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover,
+.bx-media-desktop .bx-layout-column-fullwidth .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover {
+    -webkit-flex: 0 0 33.25%;
+    -ms-flex: 0 0 33.25%;
+    flex: 0 0 33.25%;
+}
+
+.bx-media-desktop .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(33.3%);
+}
+.bx-media-desktop .bx-layout-column-thin .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(100%);
+}
+.bx-media-desktop .bx-layout-column-half .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(50%);
+}
+
+.bx-media-desktop .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(6.25%);
+}
+.bx-media-desktop .bx-layout-column-thin .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(25.0%);
+}
+.bx-media-desktop .bx-layout-column-half .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(10.0%);
+}
+
+
+/*--- Unit ---*/
+p.bx-base-pofile-unit-thumb.bx-def-icon-size {
+    font-size: 1.125rem;
+}
+p.bx-base-pofile-unit-thumb.bx-def-thumb-size {
+    font-size: 1.75rem;
+}
+p.bx-base-pofile-unit-thumb.bx-def-ava-size {
+    font-size: 2.375rem;
+}
+p.bx-base-pofile-unit-thumb.bx-def-ava-big-size {
+    font-size: 3rem;
+}
+
+
+/*--- Unit Meta ---*/
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor {
+    -webkit-justify-content: center;
+    justify-content: center;
+    -webkit-align-items: center;
+    align-items: center;
+
+    width: 100%;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor > li {
+    -webkit-flex: 1 1 auto;
+    flex: 1 1 auto;
+    margin: 0 0.25rem;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor > li.bx-menu-item-nl {
+    margin: 0;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor .bx-menu-item-nl ~ li {
+    margin-top: 0.5rem;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor .bx-menu-item-nl ~ li .bx-base-profile-unit-meta-item {
+    display: block;
+    width: 100%;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor .bx-menu-item-nl ~ li .bx-base-profile-unit-meta-item .bx-btn {
+    display: block;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor .bx-menu-item-nl ~ li .bx-base-profile-unit-meta-item {
+    padding: 0;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor .bx-menu-item-nl ~ li .bx-base-profile-unit-meta-item .bx-btn {
+    text-align: center;
+}
+.bx-base-pofile-unit-with-cover .bx-base-general-unit-meta ul.bx-menu-custom.bx-menu-custom-hor .bx-base-pofile-unit .bx-def-icon-size {
+    width: 1.5rem;
+    height: 1.5rem;
+}
+
+
+/*--- Entry: Profile Cover ---*/
+.bx-base-pofile-cover-wrapper.bx-no-cover .bx-base-pofile-cover-bg  {
+    height: 50%;
+}
+.bx-base-pofile-cover-wrapper.bx-no-cover .bx-base-pofile-cover-info {
+    padding-top: 1rem;
+}
+.bx-base-pofile-cover-wrapper.bx-no-cover .bx-base-pofile-ci-cnt {
+    margin-top: 0;
+}
+.bx-base-profile-cover-meta .bx-menu-custom.bx-menu-custom-hor {
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+}
+.bx-base-profile-cover-meta .bx-menu-custom.bx-menu-custom-hor li {
+    margin-right: 1.25rem;
+}
+.bx-base-profile-cover-meta .bx-menu-custom.bx-menu-custom-hor li:last-child {
+    margin-right: 0;
+}
+.bx-base-profile-cover-meta .bx-menu-custom.bx-menu-custom-hor li .sys-meta-div {
+    display: none;
+}
+.bx-base-profile-cover-meta .bx-menu-custom.bx-menu-custom-hor li .bx-base-bages-container {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: flex-start;
+    align-items: flex-start;
+}
+
+/*--- Entry: Profile Actions ---*/
+div.bx-base-general-entity-actions {
+    position: relative;
+    width: 100%;
+}
+.bx-base-pofile-cover-actions div.bx-base-general-entity-actions {
+    position: absolute;
+}
+.bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor {
+    -webkit-justify-content: center;
+    justify-content: center;
+}
+.bx-media-desktop .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor {
+    -webkit-justify-content: flex-end;
+    justify-content: flex-end;
+}
+div.bx-base-general-entity-actions .bx-stl-mil-wo-gaps-sm .sys-action-element-holder > a {
+    padding: 0.375rem 0.5rem 0.375rem 0.5rem;
+}
+div.bx-base-general-entity-actions .bx-popup .bx-stl-mil-wo-gaps-sm .sys-action-element-holder > a {
+    padding-left: 1.0rem;
+    padding-right: 1.0rem;
+}
+div.bx-base-general-entity-actions .bx-menu-custom-hor > li .sys-action-element-holder a {
+    display: block;
+}
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item {
+    border-color: transparent;
+    border-radius: 0;
+    box-shadow: none;
+}
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item,
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item .bx-base-general-entity-action,
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item .sys-action,
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item .sys-action-cnt,
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item .sys-action-element-holder {
+    width: 100%;
+}
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item a {
+    width: 100%;
+    box-sizing: border-box;
+}
+div.bx-base-general-entity-actions .bx-menu-custom-hor li.bx-menu-item-more-auto .bx-popup .bx-menu-custom-ver .bx-menu-item .sys-action-counter-holder:not(.bx-score-counter-holder) {
+    margin-right: 1rem;
+}
+
+.bx-media-desktop .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > .bx-menu-item-more-auto > .bx-base-general-entity-action > a > .bx-mi-text,
+.bx-media-tablet .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > .bx-menu-item-more-auto > .bx-base-general-entity-action > a > .bx-mi-text {
+    display: none;
+}
+.bx-media-phone .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > .bx-menu-item-more-auto > .bx-base-general-entity-action > a > .bx-mi-text {
+    display: inline;
+}
+.bx-media-phone .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > li:not(.bx-menu-item-more-auto) a,
+.bx-media-phone .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > li:not(.bx-menu-item-more-auto) .sys-action-do,
+.bx-media-phone .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > li.bx-menu-item-more-auto > span > a {
+    -webkit-flex-direction: column;
+    flex-direction: column;
+    -webkit-align-items: center;
+    align-items: center;
+
+    height: auto;
+}
+.bx-media-phone .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > li:not(.bx-menu-item-more-auto) a span,
+.bx-media-phone .bx-base-pofile-cover-actions div.bx-base-general-entity-actions .bx-menu-custom-hor > li.bx-menu-item-more-auto > span > a span.bx-mi-text {
+    margin: 0;
+    padding: 0;
+}
+
+/*--- Entry: Profile Cover block ---*/
+.bx-base-profile-cover-block-wrapper .bx-base-pofile-cover-actions div.bx-base-general-entity-actions{
+    position: relative;
+}
+
+/*--- Entry: Profile Description block ---*/
+.bx-base-profile-entity-content.bx-def-vanilla-html {
+    margin-top: 1.5rem;
+    margin-bottom: 1.5rem;
+}

+ 6 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_profile/menu_custom_actions.html

@@ -0,0 +1,6 @@
+<ul id="__html_id__" class="bx-menu-custom bx-menu-custom-hor bx-menu-hor-inline<bx_if:show_more_auto_class> bx-menu-more-auto</bx_if:show_more_auto_class> bx-menu-object-__object__ flex items-stretch space-y-0 space-x-3">
+    <bx_repeat:menu_items>
+        <li class="bx-menu-item bx-menu-item-__name____class__ bx-stl-mil-wo-gaps-sm bx-stl-mib group">__item__</li>
+    </bx_repeat:menu_items>
+</ul>
+__js_code__

+ 4 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/mod_profile/menu_custom_item_actions.html

@@ -0,0 +1,4 @@
+<span class="__class_wrp__ truncate">
+    <a class="__class_link__ bx-stl-mil-gaps-sm flex flex-row flex-nowrap sm:items-center" href="__link__" onclick="__onclick__" title="__title_attr__"__attrs__><span class="bx-mi-icon flex items-center justify-center h-5 w-5"><bx_if:icon><i class="sys-icon __icon__"></i></bx_if:icon><bx_if:image><img class="h-5 w-5" style="background-image:url(__icon_url__)" src="<bx_icon_url:spacer.gif />" /></bx_if:image></span><bx_if:title><span class="bx-mi-text ml-1.5 first:ml-0 whitespace-nowrap truncate">__title__</span></bx_if:title></a>
+    <bx_if:addon>__addon__</bx_if:addon>
+</span>

+ 310 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/common.css

@@ -0,0 +1,310 @@
+/*
+import url(../../../../../../../template/css/common.css);
+*/
+
+/*--- General ---*/
+.bx-clear {
+    clear:both;
+    float:none;
+    display:block;
+    width: 0px;
+    height: 0px;
+    font-size:1px;
+}
+.bx-clearfix:before,
+.bx-clearfix:after {
+    content:"";
+    display:table;
+}
+.bx-clearfix:after {
+    clear:both;
+}
+
+/*--- Application ---*/
+.bx-main.bx-pt-application .bx-menu-toolbar-padding {
+    padding-top: 0;
+}
+.bx-main.bx-pt-application .bx-main-content .bx-main-column .bx-def-page-width {
+    width: 100%;
+}
+.bx-main.bx-pt-application .bx-main-column.narrow.bx-mc-narrowed .bx-mc-cnt {
+    padding: 0;
+}
+
+/*--- Design Boxes ---*/
+.bx-db-container {
+    position:relative;
+}
+.bx-db-header {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+    -ms-flex-align: center;
+    align-items: center;
+
+    -webkit-flex-wrap: nowrap;
+    -ms-flex-wrap: nowrap;
+    flex-wrap: nowrap;
+}
+.bx-db-container.bx-dbc-nopadding > .bx-db-header {
+    padding-left: 0;
+    padding-right: 0;
+}
+.bx-db-container.bx-dbc-nobg .bx-db-divider {
+    display: none;
+}
+.bx-db-title {
+    -webkit-flex: 1 1 auto;
+    -ms-flex: 1 1 auto;
+    flex: 1 1 auto;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.bx-db-menu {
+    -webkit-flex: 1 2 auto;
+    -ms-flex: 1 2 auto;
+    flex: 1 2 auto;
+
+    max-width: 75%;
+}
+
+.bx-media-phone .bx-db-menu {
+    max-width: 65%;
+}
+
+.bx-db-menu-tab {
+    margin-left: 5px;
+    text-align: right;
+}
+
+.bx-db-menu-tab-active {
+    text-decoration:underline;
+}
+
+.bx-db-menu-tab-btn a {
+    text-decoration:none;
+}
+
+.bx-db-menu-tab-btn ul > li {
+    display: flex;
+}
+
+.bx-db-menu .sys-icon-a {
+    vertical-align:middle;
+}
+
+.bx-db-menu-popup {
+    text-align: left;
+}
+
+.bx-db-content {
+    position: relative;
+}
+
+.bx-content-padding-block {
+    padding: 1rem;
+}
+
+.bx-db-content .bx-db-help {
+    position: absolute;
+    top: 0;
+    right: 0;
+    width: 2.0rem;
+    height: 2.0rem;
+    border-radius: 2rem;
+    background-color: rgba(0, 0, 0, 0.1);
+    line-height: 2rem;
+    text-align: center;
+}
+
+.bx-db-help-popup {
+    max-width: 25rem;
+    max-height: 25rem;
+    overflow: auto;
+}
+
+/*--- Design Boxes Menu ---*/
+.bx-db-menu ul li {
+    white-space: nowrap;
+}
+.bx-db-menu ul li:not(.bx-stl-mil-sm) {
+    border-radius: 0;
+}
+.bx-db-menu ul.bx-menu-hor,
+.bx-db-menu ul.bx-menu-custom.bx-menu-custom-hor,
+.bx-db-menu ul.bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto:not(.bx-menu-submenu-more-auto) {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-justify-content: flex-end;
+    justify-content: flex-end;
+}
+.bx-db-menu ul.bx-menu-hor > li:not(.bx-stl-mil-sm),
+.bx-db-menu ul.bx-menu-custom.bx-menu-custom-hor > li:not(.bx-stl-mil-sm) {
+    display: block;
+
+    -webkit-flex: 0 1 auto; 
+    -ms-flex:  0 1 auto; 
+    flex:  0 1 auto;
+
+    padding: 0 0.25rem;
+
+    border-bottom: 1px solid transparent;
+}
+.bx-db-menu .bx-menu-custom.bx-menu-custom-hor > li:not(.bx-stl-mil-sm) > span {
+    display: block;
+
+    margin: 0;
+    padding: 0;
+}
+.bx-db-menu ul.bx-menu-hor > li a.bx-btn,
+.bx-db-menu ul.bx-menu-custom.bx-menu-custom-hor > li a.bx-btn {
+    display: inline-block;
+    float: none;
+}
+.bx-db-menu ul.bx-menu-hor > li a > span,
+.bx-db-menu ul.bx-menu-custom.bx-menu-custom-hor > li a > span {
+    vertical-align: middle;
+}
+.bx-db-menu ul > li:not(.bx-menu-item-more-auto) a .bx-mi-icon {
+    display: none;
+}
+.bx-db-menu ul.bx-menu-submenu-more-auto {
+    line-height: normal;
+}
+.bx-db-menu ul li:not(.bx-menu-item-more-auto) a span,
+.bx-db-menu .bx-menu-item-more-popup ul.bx-menu-custom.bx-menu-submenu-more-auto li:not(.bx-menu-item-more-auto) a span,
+.bx-db-menu .bx-popup .bx-db-menu-popup ul.bx-menu-custom.bx-menu-custom-ver li a > span,
+.bx-db-menu .bx-popup .bx-db-menu-popup ul.bx-menu-ver li a > div > span {
+    margin: 0;
+}
+.bx-db-menu ul.bx-menu-hor li.bx-menu-tab-active,
+.bx-db-menu ul.bx-menu-custom.bx-menu-custom-hor li.bx-menu-tab-active {
+    border-bottom: 0;
+}
+.bx-db-menu ul.bx-menu-custom-ver li.bx-menu-item-more-auto {
+    display: none;
+}
+
+
+/*--- Popup boxes ---*/
+html.bx-popup-lock,
+body.bx-popup-lock {
+    overflow: hidden;
+}
+
+.bx-popup-transitions {
+    -webkit-transition: opacity 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out;
+    transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
+}
+
+.bx-popup-inactive {
+    -webkit-opacity: 0;
+    opacity: 0;
+
+    -webkit-transform: scale(0.75);
+    transform: scale(0.75);
+}
+
+.bx-popup-active {
+    max-height:100%;
+    overflow-y:auto;
+
+    -webkit-opacity: 1;
+    opacity: 1;
+
+    -webkit-transform: scale(1);
+    transform: scale(1);
+
+    -webkit-transition: opacity 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out;
+    transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
+}
+.bx-popup-fog {
+    position: fixed;
+    top: 0;
+    left: 0;
+    -webkit-backface-visibility: hidden;
+}
+.bx-popup-menu .bx-popup-close-wrapper {
+    display: none;
+}
+.bx-popup-menu .bx-popup-content-indent {
+    padding: 0px !important;
+}
+.bx-popup-menu ul.bx-menu-ver,
+.bx-popup-menu ul.bx-menu-verlit,
+.bx-popup-menu ul.bx-menu-custom-ver,
+.bx-popup-menu.bx-popup-menu-main.sys-add-content ul {
+    margin-top: 0.5rem;
+    margin-bottom: 0.5rem;
+}
+
+
+/*--- Loading indicator ---*/
+.bx-loading-ajax {
+    position: absolute;
+    width: 6rem;
+    height: 6rem;
+    margin-left: auto;
+    margin-right: auto;
+
+    background-color: transparent;
+
+    border-radius: 0.5rem;
+    -moz-border-radius: 0.5rem;
+    -webkit-border-radius: 0.5rem;
+
+    text-align: center;
+    color: #CCCCCC;
+}
+.bx-loading-ajax.static {
+    position: static;
+}
+.bx-loading-ajax-btn {
+    position: relative;
+    display: inline-block;
+    vertical-align: top;
+
+    min-width: 2.0rem;
+
+    margin-left: 0.25rem;
+}
+
+button.bx-btn:focus,
+button.bx-btn:focus .bx-loading-ajax-btn {
+    outline: 0;	
+}
+
+/*-- Show More --*/
+.bx-overflow-ready {
+    max-height: 16rem;
+    overflow: hidden;
+}
+.bx-overflow:before {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    height: 20%;
+
+    content: '';
+}
+
+.bx-show-more {
+    padding-top: 0.25rem;
+    padding-bottom: 0.25rem;
+
+    text-align: center
+}
+
+/*-- Flickity: Tailwind overwrite --*/
+.flickity-enabled .flickity-viewport .flickity-slider img,
+.flickity-enabled .flickity-viewport .flickity-slider video {
+    display: inline;
+    max-width: none;
+}

+ 370 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/forms.css

@@ -0,0 +1,370 @@
+/*--
+import url(../../../../../../../template/css/forms.css);
+--*/
+
+.bx-form-advanced-wrapper .bx-form-section-wrapper:first-child {
+    margin-top:0;
+}
+
+.bx-form-advanced-wrapper .bx-form-section-divider:first-child {
+    border-top:none; 
+    padding-top:0; 
+}
+
+.bx-form-advanced-wrapper .bx-form-section-divider:first-child .bx-form-section-content {
+    padding-top:0; 
+}
+
+.bx-form-advanced-wrapper .bx-form-section-wrapper:last-child .bx-form-section-content {
+    padding-bottom:0;
+}
+
+.bx-form-advanced-wrapper .bx-form-section-wrapper:first-child .bx-form-row-view-wrapper:first-child {
+    padding-top:0;
+}
+
+.bx-form-input-wrapper-pgc {
+    position: relative;
+}
+
+
+/*-- Section Toggler ---*/
+.bx-form-section-wrapper {
+    position: relative;
+}
+
+.bx-form-section {
+    margin: 0;
+    padding: 0;
+    border: none;
+}
+
+.bx-form-section-header .bx-form-section-title {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+
+    line-height: 1.25rem;
+    text-transform: uppercase;
+}
+
+.bx-form-section-header .bx-form-section-title u {
+    cursor: pointer;
+}
+
+.bx-form-section-header span {
+    width: 100%;
+    padding-left: 1.25rem;
+
+    white-space: nowrap;
+    text-transform: none;
+    font-size: 0.75rem;
+}
+
+.bx-form-section-hidden .bx-form-section-content {
+    display:none;
+}
+
+.bx-form-collapsable .bx-form-section-toggler {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    justify-content: center;
+
+    width: 1.25rem;
+    height: 1.25rem;
+
+    text-decoration: none;
+
+    -moz-transform: rotate(90deg);
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    -o-transform: rotate(90deg);
+
+    -webkit-transition: all 0.5s ease;
+    -moz-transition: all 0.5s ease;
+    -ms-transition: all 0.5s ease;
+    -o-transition: all 0.5s ease;
+
+    line-height: 1.25rem;
+}
+
+.bx-form-collapsed .bx-form-section-toggler {
+    -moz-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+}
+
+.bx-form-section-toggler .sys-icon {
+    font-size:0.875rem;
+}
+
+/*--- One Line fields ---*/
+.bx-form-element-wrapper-oneline .bx-form-element {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-flex-flow: row nowrap;
+    flex-flow: row nowrap;
+    -webkit-align-items: flex-start;
+    align-items: flex-start;
+    -webkit-justify-content: flex-start;
+    justify-content: flex-start;
+}
+
+
+/*-- Form field: Password --*/
+.bx-artificer .bx-form-input-wrapper-password > a {
+    position: absolute;
+    z-index: 1000;
+    
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-justify-content: center;
+    justify-content: center;
+
+    top: 0;
+    right: 0;    
+    height: 100%;
+
+    margin: 0 0.5rem;
+}
+.bx-artificer .bx-form-input-password {
+    position: relative;
+
+    -moz-box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+
+    width: 100%;
+    height: 100%;
+
+    margin: 0;
+    padding: 0.5rem 0;
+
+    border: 0;
+    background-color: transparent;
+}
+.bx-artificer .bx-form-input-password:focus {
+    border-color: transparent;
+    outline: none;
+    box-shadow: none;
+}
+
+
+/*-- Form field: Price --*/
+.bx-form-element .bx-form-value .bx-form-input-wrapper-price {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: stretch;
+    align-items: stretch;
+}
+.bx-form-element .bx-form-value .bx-form-input-wrapper-price span {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+
+    width: auto;
+    border-right-width: 0;
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+}
+.bx-form-element .bx-form-value .bx-form-input-price:not(:first-child) {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+}
+
+
+/*-- Form field: Date/Time Pickers --*/
+.bx-form-datepicker-modal {
+    z-index: 10001 !important;
+}
+
+
+/*-- Form field: Switcher --*/
+.bx-switcher-cont input {
+   display: none !important;
+}
+
+
+/*-- Form field: Checkbox/Radio Set --*/
+.bx-form-input-wrapper-checkbox_set label,
+.bx-artificer .bx-form-input-wrapper-radio_set label {
+    margin-left: 0.5rem;
+    vertical-align: text-bottom;
+}
+
+
+/*--- Form field: File ---*/
+.bx-form-input-wrapper-file .bx-btn {
+    display: inline-block;
+    float: none;
+}
+.bx-form-input-file {
+    position: fixed;
+    top: -1000px;
+
+    border: none;
+    background-color: transparent;
+    visibility: hidden;
+}
+
+
+/*--- Form field: Location ---*/
+.bx-form-element .bx-form-value input,
+.bx-form-element .bx-form-value select {
+    display: inline-block;
+}
+.bx-form-element .bx-form-input-location-country,
+.bx-form-element .bx-form-input-location-zip,
+.bx-form-element .bx-form-input-location-state,
+.bx-form-element .bx-form-input-location-city {
+    width:49%;
+}
+.bx-form-element .bx-form-input-location-street {
+    width:83%;
+}
+.bx-form-element .bx-form-input-location-street_number {
+    width:15%;
+}
+.bx-form-element .bx-form-input-location-street_number,
+.bx-form-element .bx-form-input-location-street,
+.bx-form-element .bx-form-input-location-state,
+.bx-form-element .bx-form-input-location-city {
+    margin-bottom: 0.25rem;
+}
+.bx-form-element .bx-form-input-location-street,
+.bx-form-element .bx-form-input-location-state,
+.bx-form-element .bx-form-input-location-country {
+    margin-left: 0.25rem;
+}
+
+.bx-form-element .bx-form-input-location-cont .bx-form-input-location-status-cont {
+    float:none;
+    width:98%;
+    line-height:normal;
+}
+.bx-form-element .bx-form-input-location-status {
+    float:left;
+}
+.bx-form-element .bx-form-input-location-copyright {
+    float:right;
+}
+
+.bx-form-element .bx-form-input-location-auto-cont {
+    display:table;
+}
+.bx-form-element .bx-form-input-location-auto-cont > div {
+    display: table-cell;
+    vertical-align: middle;
+}
+
+
+/*--- Form field: Auto-siggestion ---*/
+
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) {
+    float: left;
+    padding: 0.125rem 0;
+    height: auto;
+    box-shadow: none;
+    min-height: 2.375rem;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) b {
+    display: block;
+    float: left;
+    margin: 0 0.125rem;
+    padding-right: 1.5rem;
+    border-radius: 1.25rem;
+
+    line-height: 2rem;
+    white-space: nowrap;
+    font-weight: normal;    
+    cursor: pointer;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) b.val-wo-icon {
+    padding-left: 1.5rem;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) b:hover {
+    opacity: 0.7;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) b:after {
+    font-family: 'sys-user', 'sys-user-fal';
+    content: "\f00d";    
+    position:absolute;    
+    padding:0 0.5em;
+    margin-left: 0.5em;
+    font-size:0.7em;
+    font-weight:bold;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels).bx-form-input-disabled b {
+    cursor: default;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels).bx-form-input-disabled b:after{
+    display: none;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) input {
+    float: left;
+    width: auto;
+    margin: 0;
+    padding: 0 0 0 0.5rem;
+    border: 0;
+    box-shadow: none;
+}
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) .bx-account-unit-wo-info,
+.bx-form-value .bx-form-input-autotoken:not(.bx-form-input-labels) .bx-base-pofile-unit-wo-info {
+    display: inline-block;
+    vertical-align: top;
+
+    margin-right: 0.5rem;
+}
+.sys-labels .bx-form-input-text.bx-form-input-autotoken b:first-child{
+    margin-left: 2px !important;
+}
+
+.sys-labels .bx-form-input-text.bx-form-input-autotoken.bx-form-input-disabled b{
+    height: 2rem;
+    line-height: 2rem;
+}
+
+.bx-form-value .sys-labels .bx-form-input-autotoken.bx-form-input-labels{
+    padding: 0 !important;
+    padding-top: 2px !important;
+}
+.sys-labels .bx-form-input-text.bx-form-input-autotoken
+{
+    min-height: 2.375rem !important;
+}
+.bx-form-value .bx-form-input-labels > a {
+    margin-left: 0.5rem;
+}
+.bx-form-value .bx-form-input-labels > a:first-child {
+    margin-left: 0;
+}
+.select2-container {
+    width:100% !important;
+}
+.bx-form-input-select {
+    -webkit-appearance:none;
+}
+
+/* tiny mce */
+.bx-form-input-wrapper-html .gray-theme.fr-toolbar.fr-top{
+   border-radius: .375rem .375rem 0 0 !important; 
+}
+.bx-form-input-wrapper-html .fr-wrapper{
+    border-radius: 0 0 .375rem .375rem !important; 
+    border-bottom-color: #CCCCCC !important;
+}
+.bx-form-input-wrapper-html .second-toolbar{
+    border-bottom:none !important;
+}
+

+ 110 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/general.css

@@ -0,0 +1,110 @@
+/*--
+import url(../../../../../../../template/css/general.css);
+--*/
+
+
+/*--- Toolbar ---*/
+.bx-toolbar-anim {
+    -webkit-transition: all .25s ease-in-out;
+    -moz-transition: all .25s ease-in-out;
+    -o-transition: all .25s ease-in-out;
+    transition: all .25s ease-in-out
+}
+.bx-toolbar-reset {
+    -webkit-transform: translateY(0);
+    -ms-transform: translateY(0);
+    transform: translateY(0)
+}
+.bx-toolbar-up {
+    -webkit-transform: translateY(-100%);
+    -ms-transform: translateY(-100%);
+    transform: translateY(-100%)
+}
+.bx-toolbar-item.bx-ti-logo a:hover {
+    text-decoration: none;
+}
+.bx-toolbar-item.bx-ti-search .bx-ti-search-button a {
+    text-decoration: none;
+}
+.bx-toolbar-item.bx-ti-search .bx-ti-search-button img {
+    width: 1.5rem;
+    height: 1.5rem;
+}
+.bx-toolbar-item.bx-ti-search .bx-tis-button-hidden {
+    display: none;
+}
+.bx-toolbar-item.bx-ti-search .bx-tis-box-shown {
+    position: absolute;
+    display: block;
+}
+.bx-toolbar-item.bx-ti-search .bx-form-advanced .bx-loading-ajax {
+    top: 0;
+    max-height: 100%;
+}
+.bx-toolbar-item.bx-ti-search .bx-form-advanced-wrapper .bx-form-section-wrapper:first-child {
+    margin-top: 0;
+}
+.bx-toolbar-item.bx-ti-search .sys-search-results-quick {
+    position: absolute;
+    z-index: 10;
+}
+
+
+/*--- Page Submenu ---*/
+.bx-menu-main-bar-cnt {
+    height: 3.25rem;
+}
+
+.bx-menu-main-bar:not(.bx-menu-more-auto) .bx-menu-main-bar-cnt > div {
+    overflow-x: auto;
+}
+
+.bx-menu-main-bar-gap.bx-menu-main-bar-hidden,
+.bx-menu-main-bar-wrapper.bx-menu-main-bar-hidden,
+.bx-menu-main-bar.bx-menu-main-bar-hidden {
+    display: none;
+}
+
+
+/*--- Profile Avatar ---*/
+.bx-db-content.bx-content-padding-block .bx-profile-avatar-cnt {
+    margin-left: -0.25rem;
+    margin-right: -0.25rem;
+}
+#bx-profile-switcher .bx-pas-list .bx-def-hr:first-child {
+    display: none;
+}
+
+/*--- Profile Stats ---*/
+.bx-menu-vertical-more-less li.bx-psmi-show-more,
+.bx-menu-vertical-more-less li.bx-psmi-show-less {
+    text-transform: uppercase;
+    font-size: 0.875rem;
+}
+
+.bx-menu-vertical-more-less li.bx-psmi-show-more:hover,
+.bx-menu-vertical-more-less li.bx-psmi-show-less:hover {
+    background-color: transparent;
+}
+
+/*--- Author Info ---*/
+.sys-author-profile .bx-menu-custom.bx-menu-custom-hor > li:first-child .bx-base-general-unit-meta-div {
+    display: none;
+}
+
+/*--- Join/Login Forms ---*/
+#sys_account .bx-form-element .bx-form-input-submit.bx-btn,
+#sys-form-login .bx-form-element .bx-form-input-submit.bx-btn {
+    width: 100%;
+    -webkit-justify-content: center;
+    justify-content: center;
+    text-align: center;
+}
+#bx-form-element-submit_text .bx-form-value {
+    text-align: right;
+}
+
+/*--- Page Type: Application ---*/
+.bx-menu-panel-item .bx-profile-avatar .bx-profile-avatar-cnt {
+    min-height: 2.5rem;
+}

+ 219 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/css/menu.css

@@ -0,0 +1,219 @@
+/*--
+import url(../../../../../../../template/css/menu.css);
+--*/
+
+ul.bx-menu-hor,
+ul.bx-menu-custom-hor,
+ul.bx-menu-notif,
+ul.bx-menu-verlit,
+ul.bx-menu-ver,
+ul.bx-menu-custom-ver,
+ul.bx-menu-main,
+ul.bx-menu-main-submenu,
+ul.bx-menu-toolbar,
+ul.bx-menu-floating-blocks-wide,
+ul.bx-menu-floating-blocks-big,
+ul.bx-menu-floating-blocks-dash,
+ul.bx-menu-floating-blocks,
+ul.bx-menu-inter,
+ul.bx-menu-inter-vert,
+ul.bx-menu-btns-ver,
+ul.bx-menu-btns-hor,
+ul.bx-menu-btns-icon-hor {
+    padding: 0;
+    margin: 0;
+    list-style: none;
+}
+
+li.bx-mi-aux {}
+li.bx-mi-hidden {
+    display: none;
+}
+
+/* --- Vertical, Vertical lite, Custom Vertical Menus ---*/
+.bx-menu-ver li,
+.bx-menu-verlit li,
+.bx-menu-custom-ver li {
+    margin-top: 1px;
+}
+.bx-menu-ver li:first-child,
+.bx-menu-verlit li:first-child,
+.bx-menu-custom-ver li:first-child {
+    margin-top: 0px;
+}
+
+/*--- Vertical, Vertical lite, Custom Vertical Menus (in Popup) ---*/
+.bx-popup .bx-menu-custom-ver li > span {
+    -webkit-flex: 1 1 auto;
+    -ms-flex: 1 1 auto;
+    flex: 1 1 auto;
+
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-justify-content: space-between;
+    justify-content: space-between;
+}
+.bx-popup .bx-menu-custom-ver li > span .bx-menu-addon {
+    padding-right: 0;
+}
+
+/* --- Horizontal, Custom Horizontal Menus --- */
+.bx-menu-custom .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item,
+.bx-menu-custom .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item a,
+.bx-menu-custom .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item > span {
+    border-radius: 0;
+}
+
+/*--- Interactive Menu ---*/
+.bx-menu-inter li.bx-menu-inter-hidden,
+.bx-menu-inter-vert li.bx-menu-inter-hidden {
+    display: none;
+}
+
+/*--- Custom Menu with More Auto ---*/
+.bx-menu-main-submenu.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto,
+.bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto {
+    display: none;
+}
+.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-item a.p-2,
+.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-item a.px-2 {
+    padding-left: 1rem;
+    padding-right: 1rem;
+}
+
+/*--- Page Main menu ---*/
+.bx-menu-main .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item,
+.bx-menu-main .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item a {
+    border-radius: 0;
+}
+
+/*--- Page Submenu ---*/
+.bx-menu-main-submenu {
+    -webkit-justify-content: center;
+    justify-content: center;
+}
+.bx-menu-main-submenu .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item > a {
+    width: 100%;
+    padding: 0.5rem 1.0rem; 
+    text-align: left;
+}
+.bx-menu-main-submenu .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-custom .bx-menu-item .bx-mi-underline {
+    display: none;
+}
+
+/*--- Toolbar Menu ---*/
+.bx-menu-toolbar .bx-menu-toolbar-item .bx-menu-item-addon {
+    position: absolute;
+    top: -0.375rem;
+    right: -0.375rem;
+    padding: 0 0.25rem;
+}
+.bx-menu-toolbar .bx-menu-toolbar-item .bx-menu-toolbar-item-unit .bx-base-pofile-unit-online {
+    display: none;
+}
+
+/*--- Account Popup ---*/
+#bx-sliding-menu-account .bx-menu-account-popup .bx-menu-item-addon.bx-def-unit-alert {
+    position: relative;
+    padding: 0 0.25rem;
+}
+#bx-sliding-menu-account .bx-menu-account-popup-profile-switcher-link {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-justify-content: center;
+    justify-content: center;
+}
+
+/*--- Add Popup ---*/
+div.bx-popup-menu-main.sys-add-content ul {
+    flex-direction: column;
+}
+
+/*--- Pannel Menu ---*/
+.bx-menu-panel {}
+
+.bx-main-column.bx-mc-narrowed .bx-menu-panel .bx-menu-panel-item .bx-mpi-toggle-hidden {
+    position: absolute;
+    display: none;
+}
+
+.bx-mc-narrowed .bx-menu-panel li .bx-stl-mil {
+    -webkit-justify-content: center;
+    justify-content: center;
+
+    padding-left: 0;
+    padding-right: 0;
+}
+.bx-mc-narrowed .bx-menu-panel li .bx-stl-mii {
+    width: 100%;
+    text-align: center;
+}
+.bx-mc-narrowed .bx-menu-panel li .bx-stl-mii,
+.bx-mc-narrowed .bx-menu-panel li .bx-stl-mii > * {
+    margin: 0;
+}
+.bx-mc-narrowed .bx-menu-panel .bx-def-thumb-size {
+    width: 2rem;
+    height: 2rem;
+}
+.bx-mc-narrowed .bx-menu-panel .bx-profile-avatar-cnt {
+    -webkit-justify-content: center;
+    justify-content: center;
+}
+
+/*--- Profile Stats/Followings Menu ---*/
+.bx-db-content .bx-profile-stats .bx-profile-avatar-cnt,
+.bx-db-content .bx-profile-stats .bx-menu-vertical-more-less,
+.bx-db-container:not(.bx-dbc-nopadding) .bx-menu-vertical-more-less,
+.bx-db-container:not(.bx-dbc-nopadding) .bx-menu-profile-followings {
+    margin: -0.75rem;
+}
+.bx-db-container:not(.bx-dbc-notitle) .bx-menu-vertical-more-less,
+.bx-db-container:not(.bx-dbc-notitle) .bx-menu-profile-followings {
+    margin-top: 0;
+}
+.bx-main.bx-pt-application .bx-main-column.narrow .bx-menu-vertical-more-less,
+.bx-main.bx-pt-application .bx-main-column.narrow .bx-menu-profile-followings {
+    margin-left: -0.75rem;
+    margin-right: -0.75rem;
+}
+
+/*--- Profile Followings Menu ---*/
+.bx-menu-ver.bx-menu-object-sys_profile_followings li .bx-menu-show {
+    display: none;
+}
+.bx-menu-ver.bx-menu-object-sys_profile_followings li .bx-menu-hide {
+    display: inline;
+}
+.bx-menu-ver.bx-menu-object-sys_profile_followings li.bx-mi-collapsed .bx-menu-show {
+    display: inline;
+}
+.bx-menu-ver.bx-menu-object-sys_profile_followings li.bx-mi-collapsed .bx-menu-hide {
+    display: none;
+}
+.bx-menu-ver.bx-menu-object-sys_profile_followings li.bx-mi-collapsed .bx-menu-item-subitems {
+    display: none;
+}
+
+/*--- Profiles meta menu ---*/
+.sys-action-counter-icon .sys-icon{
+    width: 1rem;
+    height: 1rem;
+    font-size: 0.75rem;
+    line-height: 1.1rem;
+    text-align: center;
+}
+.sys-action-counter-icon .sys-icon.sys-icon-emoji{
+    line-height: 1rem;
+}
+.sys-action-counter-iconset .bx-def-icon-size{
+    width: 1.5rem;
+    height: 1.5rem;
+}
+.sys-action-counter-iconset .bx-base-pofile-unit-wo-info,
+.sys-action-counter-iconset .sys-action-counter-icon
+{
+    margin-left: -.25rem;
+}

+ 14 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/menu_horizontal.html

@@ -0,0 +1,14 @@
+<ul class="bx-menu-hor bx-menu-object-__object__ flex flex-row space-x-1">
+    <bx_repeat:menu_items>
+        <li class="bx-menu-item __name__ __class_add__ bx-stl-mil-sm group">
+            <a class="__name__ flex flex-2 items-center truncate" href="__link__" onclick="__onclick__"__attrs__>
+                <span class="bx-menu-item-icon bx-stl-mii group-hover:text-gray-700 dark:group-hover:text-gray-300">
+                    <bx_include_auto:menu_icon.html />
+                </span>
+                <bx_if:title>
+                    <span class="bx-menu-item-title bx-stl-mit">__title__</span>
+                </bx_if:title>
+            </a>
+        </li>
+    </bx_repeat:menu_items>
+</ul>

+ 13 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/menu_toolbar.html

@@ -0,0 +1,13 @@
+<ul class="bx-menu-toolbar bx-menu-object-__object__ flex items-center pr-0 md:pr-2">
+    <bx_repeat:menu_items>
+        <li id="bx-menu-toolbar-item-__name__" class="bx-menu-toolbar-item bx-menu-item-__name__ group relative inline-flex items-center ml-2 first:ml-0 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 text-base font-medium leading-6 border border-transparent hover:border-gray-200/50 active:border-gray-300 dark:hover:border-gray-700/50 dark:active:border-gray-700 bg-gray-100 dark:bg-gray-700/50 active:bg-gray-300 dark:active:bg-black/50 hover:bg-gray-200/50 dark:hover:bg-gray-700/50 rounded-full __class_add__">
+            <a href="__link__" onclick="__onclick__" class="inline-block rounded-full __class_add_a__"__attrs__>
+                <bx_if:icon><span class="relative flex items-center justify-center h-8 w-8 md:h-10 md:w-10"><i class="sys-icon __icon__"></i></bx_if:icon>
+                <bx_if:icon-a><i class="sys-icon-a" data-rotate="down" data-icon="__icon-a__" data-color="#fff"></i></bx_if:icon-a>
+                <bx_if:image><img class="" src="__icon_url__" /></bx_if:image>
+                <bx_if:icon-html><span class="relative flex items-center justify-center h-8 w-8 md:h-10 md:w-10">__icon__</span></bx_if:icon-html>
+                <bx_if:unit><div class="bx-menu-toolbar-item-unit">__unit__</div></bx_if:unit><bx_if:addon>__addonf__</bx_if:addon><bx_if:title><span class="bx-menu-toolbar-item-title sr-only">__title__</span></bx_if:title>
+            </a>
+        </li>
+    </bx_repeat:menu_items>
+</ul>

+ 118 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/data/template/system/pt_application.html

@@ -0,0 +1,118 @@
+<bx_include_auto:_header.html />
+<div class="bx-main bx-pt-application <bx_injection:injection_main_class />">
+    <bx_injection:top />
+    <!-- BEG: Navigation -->
+    <nav class="fixed z-30 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700">
+        <div class="px-3 py-3 lg:px-5 lg:pl-3">
+            <div class="flex items-center justify-between">
+                <div class="flex flex-1 items-center justify-start">
+                    <!-- Mobile: Hamburger -->
+                    <div class="flex-none items-center lg:hidden mr-4 hidden">
+                        <bx_menu:sys_toolbar_site />
+                    </div>
+
+                    <button id="toggleSidebar" aria-expanded="true" aria-controls="sidebar" class="hidden p-2 mr-6 text-gray-600 rounded cursor-pointer lg:inline hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-white dark:hover:bg-gray-700">
+                      <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg>
+                    </button>
+                    <button id="toggleSidebarMobile" aria-expanded="true" aria-controls="sidebar" class="p-2 mr-2 text-gray-600 rounded cursor-pointer lg:hidden hover:text-gray-900 hover:bg-gray-100 focus:bg-gray-100 dark:focus:bg-gray-700 focus:ring-2 focus:ring-gray-100 dark:focus:ring-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
+                      <svg id="toggleSidebarMobileHamburger" class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg>
+                      <svg id="toggleSidebarMobileClose" class="hidden w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
+                    </button>
+                    <!-- Logo -->
+                    <div id="bx-logo-container" class="bx-toolbar-item bx-ti-left bx-ti-logo flex-none items-center">
+                        <bx_injection:injection_logo_before />
+                        __main_logo__
+                        <bx_injection:injection_logo_after />
+                    </div>
+                    <!-- Menu -->
+                    <div class="bx-toolbar-item bx-ti-menu flex-2 w-64 ml-4">
+                        <div id="bx-menu-toolbar-1-container" class="bx-toolbar-item bx-ti-menu w-full">
+                            <bx_menu:sys_application />
+                        </div>
+                    </div>
+                    <!-- Search -->
+                    <div class="bx-toolbar-item bx-ti-search flex flex-1 items-center justify-end">
+                        <div class="bx-ti-search-box flex items-start md:min-w-88 mx-4 bg-white dark:bg-gray-800 rounded-md shadow-lg lg:shadow-none hidden lg:block">
+                            <div class="relative w-full">__sys_site_search__</div>
+                        </div>
+                        <div class="bx-ti-search-button group relative inline-flex lg:hidden items-center mx-2 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 text-base font-medium leading-6 border border-transparent hover:border-gray-200/50 active:border-gray-300 dark:hover:border-gray-700/50 dark:active:border-gray-700 bg-gray-100 dark:bg-gray-700/50 active:bg-gray-300 dark:active:bg-black/50 hover:bg-gray-200/50 dark:hover:bg-gray-700/50 rounded-full">
+                            <a href="javascript:void(0)" onclick="javascript:bx_site_search_show(this)">
+                                <span class="relative flex items-center justify-center h-8 w-8 md:h-10 md:w-10">
+                                    <bx_image_auto:search />
+                                </span>
+                            </a>
+                        </div>
+                    </div>
+                </div>
+                <div class="flex items-center">
+                    <!-- Members Toolbar -->
+                    <bx_menu:sys_toolbar_member />
+                </div>
+            </div>
+        </div>
+    </nav>
+    <!-- END: Navigation -->
+
+    <div class="bx-main-content flex pt-16 overflow-hidden">
+        <!-- BEG: Sidebar -->
+        <aside id="sidebar" class="bx-main-column narrow fixed top-0 left-0 z-20 flex flex-col flex-shrink-0 hidden w-64 h-full pt-16 duration-75 lg:flex transition-width" aria-label="Sidebar">
+            <div class="bx-mc-border relative flex flex-col flex-1 min-h-0 pt-0 bg-white border-r border-gray-200 dark:bg-gray-800 dark:border-gray-700">
+                <div class="flex flex-col flex-1 py-2 overflow-y-auto">
+                    <div class="bx-mc-cnt flex-1 px-4 space-y-1 bg-white divide-y divide-gray-200 dark:bg-gray-800 dark:divide-gray-700">
+                        <bx_menu:sys_site_panel />
+                    </div>
+                </div>
+                <div class="absolute bottom-0 left-0 justify-center hidden w-full p-4 space-x-4 lg:flex" sidebar-bottom-menu>
+                    <!-- Some button based menu may be here -->
+                </div>
+            </div>
+        </aside>
+        <div class="fixed inset-0 z-10 hidden bg-gray-900/50 dark:bg-gray-900/90" id="sidebarBackdrop"></div>
+        <!-- END: Sidebar -->    
+
+        <!-- BEG: Main Content -->
+        <div id="main-content" class="bx-main-column wide relative w-full h-full overflow-y-auto lg:ml-64">
+            <main>
+                <bx_injection:injection_between_cover_logo />
+                __cover__
+                <bx_injection:injection_between_cover_top_menu />
+                <div id="bx-menu-main-bar-wrapper" class="bx-menu-main-bar-wrapper bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800 __site_submenu_hidden__">
+                    <div id="bx-menu-main-bar" class="bx-menu-main-bar __site_submenu_class__ mx-auto px-4 sm:px-6 lg:px-8 box-border">
+                        <div class="bx-menu-main-bar-cnt relative -mb-px">
+                            <div class="absolute w-full text-center">
+                                <bx_injection:injection_top_menu_before />
+                                <bx_menu:sys_site_submenu />
+                                <bx_injection:injection_top_menu_after />
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <bx_injection:injection_between_content_menu />
+                <div id="bx-content-wrapper">
+                    __informer__
+                    <div class="bx-page-wrapper mx-auto px-3 md:px-4 lg:px-6 box-border">
+                        <div id="bx-content-container" class="bx-content-container">
+                            <div id="bx-content-main" class="bx-content-main my-2 lg:my-3">
+                                <bx_injection:injection_content_before />
+                                __page_main_code__
+                                <bx_injection:injection_content_after />
+                                <bx_injection:banner_bottom />
+                            </div> <!-- #bx-content-main -->
+                            <bx_injection:injection_between_content_footer />
+                        </div> <!-- #bx-content-container -->
+                    </div> <!-- .bx-page-wrapper -->
+                </div> <!-- #bx-content-wrapper -->
+            </main>
+            <footer class="p-4 m-4 bg-white rounded-lg shadow md:flex md:items-center md:justify-between md:p-6 xl:p-8 dark:bg-gray-800">
+                <bx_injection:injection_footer_before />
+                <div id="bx-menu-bottom">
+                    <bx_menu:sys_footer />
+                </div>
+                <bx_injection:injection_footer_after />
+            </footer>
+        </div>
+        <!-- END: Main Content -->
+    </div>
+    <bx_menu:sys_site_action />
+</div> <!-- .bx-main -->
+<bx_include_auto:_footer.html />

+ 68 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/config.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Artificer Artificer template
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_TEMPLATE,
+    'name' => 'bx_artificer',
+    'title' => 'Artificer',
+    'note' => 'Design template',
+    'version' => '13.0.5',
+    'vendor' => 'Boonex',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/artificer/',
+    'home_uri' => 'artificer',
+
+    'db_prefix' => 'bx_artificer_',
+    'class_prefix' => 'BxArtificer',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Artificer Template',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'clear_db_cache' => 1
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'clear_db_cache' => 1
+    ),
+    'enable' => array(
+        'execute_sql' => 1
+    ),
+    'disable' => array(
+        'execute_sql' => 1
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 50 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/langs/en.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string name="_bx_artificer_wgt_cpt"><![CDATA[Artificer]]></string>
+
+    <!-- Settings -->
+    <string name="_bx_artificer_stg_cpt_type"><![CDATA[Artificer]]></string>
+
+    <string name="_bx_artificer_stg_cpt_category_system"><![CDATA[General]]></string>
+    <string name="_bx_artificer_stg_cpt_option_switcher_name"><![CDATA[Name in Template Switcher]]></string>	
+    <string name="_bx_artificer_stg_cpt_option_page_width"><![CDATA[Page Width]]></string>
+    <string name="_bx_artificer_stg_cpt_option_header_stretched"><![CDATA[Stretched Header]]></string>
+
+    <string name="_bx_artificer_stg_cpt_category_styles_custom"><![CDATA[Custom Styles]]></string>
+    <string name="_bx_artificer_stg_cpt_option_styles_custom"><![CDATA[Custom Styles]]></string>
+    <string name="_bx_artificer_stg_cpt_option_images_custom"><![CDATA[Custom Images]]></string>
+    <string name="_bx_artificer_stg_cpt_option_images_custom_inf"><![CDATA[Each line represents an image. Line format: <b>name</b> => <b>value</b> => <b>type</b> => <b>class</b><br />Where <b>type</b> and/or <b>class</b> may be omitted. Available types are <b>ic</b> - icon (Font Awesome), <b>im</b> - image (file name or URL), <b>sc</b> - source code (SVG).]]></string>
+
+    <!-- Pages -->
+    <string name="_bx_artificer_page_block_title_splash"><![CDATA[Splash]]></string>
+    <string name="_bx_artificer_page_block_title_splash_lite"><![CDATA[Explore]]></string>
+
+    <!-- Menus -->
+    <string name="_bx_artificer_lmi_cpt_styles"><![CDATA[Styles]]></string>
+
+    <string name="_bx_artificer_menu_template_title_sidebar_site"><![CDATA[Site Sidebar Navigation]]></string>
+    <string name="_bx_artificer_menu_title_sidebar_site"><![CDATA[Site Sidebar Navigation]]></string>
+
+    <!-- Other -->
+    <string name="_bx_artificer_txt_close_sidebar"><![CDATA[Close sidebar]]></string>
+
+    <string name="_bx_artificer_txt_color_scheme_light"><![CDATA[Light]]></string>
+    <string name="_bx_artificer_txt_color_scheme_dark"><![CDATA[Dark]]></string>
+    <string name="_bx_artificer_txt_color_scheme_system"><![CDATA[System]]></string>
+
+    <string name="_bx_artificer_txt_splash_welcome_l1"><![CDATA[Welcome to]]></string>
+    <string name="_bx_artificer_txt_splash_welcome_l2"><![CDATA[the community]]></string>
+    <string name="_bx_artificer_txt_splash_welcome_l3"><![CDATA[The best social media network for people to connect, collaborate, share content and inspire each other.]]></string>
+    <string name="_bx_artificer_txt_splash_welcome_l4"><![CDATA[Powered by <a class="font-medium underline" href="https://una.io">UNA Community Management System</a>.]]></string>
+    <string name="_bx_artificer_txt_splash_welcome_a1"><![CDATA[Create Account]]></string>
+    <string name="_bx_artificer_txt_splash_welcome_a2"><![CDATA[Login]]></string>
+    <string name="_bx_artificer_txt_splash_stats_l1"><![CDATA[We rise by helping others]]></string>
+    <string name="_bx_artificer_txt_splash_stats_l2"><![CDATA[Make new friends, follow interesting creators and stay in touch with your community.]]></string>
+    <string name="_bx_artificer_txt_splash_stats_c1"><![CDATA[members]]></string>
+    <string name="_bx_artificer_txt_splash_stats_c2"><![CDATA[posts]]></string>
+    <string name="_bx_artificer_txt_splash_stats_c3"><![CDATA[comments]]></string>
+    <string name="_bx_artificer_txt_splash_login_title"><![CDATA[Log in to your account]]></string>
+    <string name="_bx_artificer_txt_splash_login_join"><![CDATA[Create New Account]]></string>
+    <string name="_bx_artificer_txt_splash_login_agreement"><![CDATA[By logging in, you agree to our <a href="{0}" class="font-medium text-gray-900 dark:text-white hover:underline">Terms of use</a> and <a href="{1}" class="dark:text-white font-medium text-gray-900 hover:underline">Privacy policy</a>.]]></string>
+    
+</resources>

ファイルの差分が大きいため隠しています
+ 6 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/sql/enable.sql


+ 49 - 0
modules/boonex/artificer/updates/13.0.4_13.0.5/source/install/sql/install.sql

@@ -0,0 +1,49 @@
+SET @sName = 'bx_artificer';
+
+
+-- SETTINGS
+INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('templates', @sName, '_bx_artificer_stg_cpt_type', 'bx_artificer@modules/boonex/artificer/|std-icon.svg', 2);
+SET @iTypeId = LAST_INSERT_ID();
+
+-- SETTINGS: Artificer template System
+INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `order`) VALUES 
+(@iTypeId, CONCAT(@sName, '_system'), '_bx_artificer_stg_cpt_category_system', 10);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, CONCAT(@sName, '_switcher_title'), '_bx_artificer_stg_cpt_option_switcher_name', 'Artificer', 'digit', '', '', '', 1), 
+(@iCategoryId, CONCAT(@sName, '_page_width'), '_bx_artificer_stg_cpt_option_page_width', '1280', 'digit', '', '', '', 2),
+(@iCategoryId, CONCAT(@sName, '_header_stretched'), '_bx_artificer_stg_cpt_option_header_stretched', '', 'checkbox', '', '', '', 3);
+
+-- SETTINGS: Artificer template Custom Styles
+INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `order`) VALUES 
+(@iTypeId, CONCAT(@sName, '_styles_custom'), '_bx_artificer_stg_cpt_category_styles_custom', 20);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, CONCAT(@sName, '_styles_custom'), '_bx_artificer_stg_cpt_option_styles_custom', '', 'text', '', '', '', 1),
+(@iCategoryId, CONCAT(@sName, '_images_custom'), '_bx_artificer_stg_cpt_option_images_custom', '', 'text', '', '', '', 10);
+
+-- SETTINGS: Artificer template Site Logo
+SET @iSystemCategoryId = (SELECT IFNULL(`id`, @iCategoryId) FROM `sys_options_categories` WHERE `name`='system' LIMIT 1);
+SET @iSystemCategoryOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_options` WHERE `category_id`=@iSystemCategoryId LIMIT 1);
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iSystemCategoryId, CONCAT(@sName, '_site_logo'), '', '0', 'digit', '', '', '', @iSystemCategoryOrder + 1),
+(@iSystemCategoryId, CONCAT(@sName, '_site_mark'), '', '0', 'digit', '', '', '', @iSystemCategoryOrder + 2),
+(@iSystemCategoryId, CONCAT(@sName, '_site_logo_alt'), '', '', 'text', '', '', '', @iSystemCategoryOrder + 3),
+(@iSystemCategoryId, CONCAT(@sName, '_site_logo_aspect_ratio'), '', '', 'digit', '', '', '', @iSystemCategoryOrder + 4),
+(@iSystemCategoryId, CONCAT(@sName, '_site_mark_aspect_ratio'), '', '', 'digit', '', '', '', @iSystemCategoryOrder + 5);
+
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '', '', 'bx_artificer@modules/boonex/artificer/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name`='home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id`=@iParentPageId);
+INSERT INTO `sys_std_widgets`(`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, @sName, 'appearance', CONCAT('{url_studio}design.php?name=', @sName), '', 'bx_artificer@modules/boonex/artificer/|std-icon.svg', '_bx_artificer_wgt_cpt', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioDesigns";}');
+INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), @iParentPageOrder + 1);

+ 51 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Attendant',
+    'version_from' => '13.0.1',
+    'version_to' => '13.0.2',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/attendant/updates/update_13.0.1_13.0.2/',
+    'home_uri' => 'attendant_update_1301_1302',
+
+    'module_dir' => 'boonex/attendant/',
+    'module_uri' => 'attendant',
+
+    'db_prefix' => 'bx_attendant_',
+    'class_prefix' => 'BxAttendant',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Attendant',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxAttendantUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 2 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/install/sql/enable.sql

@@ -0,0 +1,2 @@
+-- MENUS
+UPDATE `sys_menu_items` SET `onclick`='oBxAttendant.showPopup(1)' WHERE `set_name`='sys_account_notifications' AND `name`='notifications-attendant';

+ 256 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/source/classes/BxAttendantModule.php

@@ -0,0 +1,256 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+define('BX_ATTENDANT_ON_PROFILE_CREATION_METHOD', 'browse_recommended');
+define('BX_ATTENDANT_ON_PROFILE_CREATION_EVENT_AFTER_REGISTRATION', 'registration');
+define('BX_ATTENDANT_ON_PROFILE_CREATION_EVENT_AFTER_CONFIRMATION', 'confirmation');
+
+class BxAttendantModule extends BxDolModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    public function actionRecomendedPopup($sModule, $sEvent, $iObjectId, $bManual)
+    {
+        $sRv = '';
+        $aModules = explode(',', getParam('bx_attendant_on_profile_creation_modules'));
+        $aModuleData = array();
+        foreach($aModules as $sModuleName){
+            if(BxDolRequest::serviceExists($sModuleName, BX_ATTENDANT_ON_PROFILE_CREATION_METHOD)){
+                $aTmp = BxDolService::call($sModuleName, BX_ATTENDANT_ON_PROFILE_CREATION_METHOD, ['unit_view' => 'showcase', 'empty_message' => false, "ajax_paginate" => false]);
+
+                if (isset($aTmp['content'])){
+                    $sTmp = $aTmp['content'];
+                    $sTmp = str_replace('bx_conn_action', 'bx_attendant_conn_action', $sTmp);
+                    $aModuleData[$sModuleName] = $sTmp;
+                }
+            }
+        }
+        $bRedirect = true; // todo setting
+        
+        $oSession = BxDolSession::getInstance();
+        $sFirstPage = $oSession->getValue('sys_entrance_url');
+        $sFirstPage = 'page.php?i=view-group-profile&id=72';
+       
+        if ($sFirstPage){
+            if ($bRedirect){
+                echo json_encode(['redirect' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($sFirstPage)]);  
+                exit();
+            }
+            else{
+                list($sPageLink, $aPageParams) = bx_get_base_url($sFirstPage);
+                if (isset($aPageParams['i']) && isset($aPageParams['id'])){
+                    $oPage = BxDolPage::getObjectInstanceByURI($aPageParams['i']);
+
+                    if ($oPage){
+                        $sModuleName = $oPage->getModule();
+                        if(bx_srv('system', 'is_module_context', [$sModuleName])){
+
+                            $oModule = BxDolModule::getInstance($sModuleName);
+                            $aTmp = $oModule->serviceBrowse([
+                                'mode' => 'recent',
+                                'params' => [
+                                    'filter' => [
+                                        'field' => 'id',
+                                        'value' => [$aPageParams['id']],
+                                        'operator' => 'in',
+                                        'table' => 'tableSearch'
+                                    ],
+                                ]
+                            ]);
+                            
+                            if (isset($aTmp['content'])){
+                                $sTmp = $aTmp['content'];
+                                $sTmp = str_replace('bx_conn_action', 'bx_attendant_conn_action', $sTmp);
+                                $aModuleData[$sModuleName. '_initial_link'] = $sTmp;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        $sRv = $this->_oTemplate->popup($aModuleData, $bManual);
+        
+        bx_alert('bx_attendant', 'show_popup', bx_get_logged_profile_id(), 0, ['module' => $sModule, 'event' => $sEvent, 'object_id' => $iObjectId, 'result' => &$sRv]);
+        
+        echo $sRv;
+    }
+    
+    /**
+     * Service methods
+     */
+    
+    /**
+     * @page service Service Calls
+     * @section bx_attendant Attendant
+     * @subsection bx_attendant-other Other
+     * @subsubsection bx_attendant-on-profile get_profile_modules
+     * 
+     * @code bx_srv('bx_attendant', 'get_profile_modules', [...]); @endcode
+     * 
+     * Get list of avaliable modules for on_profile_creation event
+     * 
+     * @return an array with avaliable modules. 
+     * 
+     * @see BxAttendantModule::serviceGetProfileModules
+     */
+    /** 
+     * @ref bx_attendant-get_profile_modules "get_profile_modules"
+     */
+    public function serviceGetProfileModules()
+    {
+        $aResult = array();
+        $BxDolModuleQuery = BxDolModuleQuery::getInstance();
+        $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
+        foreach($aModules as $aModule){
+            if(BxDolRequest::serviceExists($aModule['name'], BX_ATTENDANT_ON_PROFILE_CREATION_METHOD)){
+                $aResult[$aModule['name']] = $aModule['title'];
+            }
+        }
+        return $aResult;
+    }
+    
+    
+    /**
+     * @page service Service Calls
+     * @section bx_attendant Attendant
+     * @subsection bx_attendant-other Other
+     * @subsubsection bx_attendant-on-profile get_options_redirect_after_show
+     * 
+     * @code bx_srv('bx_attendant', 'get_options_redirect_after_show', [...]); @endcode
+     * 
+     * Get list avaliable redirct pages
+     * 
+     * @return an array with avaliable redirct pages. 
+     * 
+     * @see BxAttendantModule::serviceGetOptionsRedirectAfterShow
+     */
+    /** 
+     * @ref bx_attendant-get_options_redirect_after_show "get_options_redirect_after_show"
+     */
+    public function serviceGetOptionsRedirectAfterShow()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aResult = [];
+        $aChoices = ['noredirect', 'homepage', 'profile', 'custom'];
+        foreach($aChoices as $sChoice) 
+            $aResult[] = array('key' => $sChoice, 'value' => _t('_bx_attendant_option_redirect_show_' . $sChoice));
+
+        return $aResult;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_attendant Attendant
+     * @subsection bx_attendant-other Other
+     * @subsubsection bx_attendant-on-profile get_popup_with_recommended_on_event_show
+     * 
+     * @code bx_srv('bx_attendant', 'get_popup_with_recommended_on_event_show', [...]); @endcode
+     * 
+     * Get list of events for on_profile_creation show
+     * 
+     * @return an array with avaliable events. 
+     * 
+     * @see BxAttendantModule::serviceGetPopupWithRecommendedOnEventShow
+     */
+    /** 
+     * @ref bx_attendant-get_popup_with_recommended_on_event_show "get_popup_with_recommended_on_event_show"
+     */
+    public function serviceGetPopupWithRecommendedOnEventShow()
+    {
+        $aResult = array();
+        $aChoices = array(BX_ATTENDANT_ON_PROFILE_CREATION_EVENT_AFTER_CONFIRMATION, BX_ATTENDANT_ON_PROFILE_CREATION_EVENT_AFTER_REGISTRATION);
+        foreach($aChoices as $sChoice)
+            $aResult[$sChoice] = _t('_bx_attendant_popup_event_after_' . $sChoice);
+        
+        return $aResult;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_attendant Attendant
+     * @subsection bx_attendant-other Other
+     * @subsubsection bx_attendant-get_profile_modules handle_action_view
+     * 
+     * @code bx_srv('bx_attendant', 'handle_action_view', [...]); @endcode
+     * 
+     * Get Include for injection
+     * 
+     * @return an include code
+     * 
+     * @see BxAttendantModule::HandleActionView
+     */
+    /** 
+     * @ref bx_attendant-handle_action_view "handle_action_view"
+     */
+    public function serviceHandleActionView()
+    {
+        $sRv = $this->_oTemplate->init();
+        
+        if (!isLogged())
+            return;
+        
+        $aEvents = $this->_oDb->getEvents(array('type' => 'active_by_action_and_profile_id', 'action' => 'view', 'profile_id' => bx_get_logged_profile_id()));
+        foreach($aEvents as $aEvent){
+            //$oRv = call_user_func_array(array($this, $aEvent['method']), array($aEvent['object_id']));
+            $oRv = $this->processPopupOnEvent($aEvent);
+            if ($oRv !== false){
+                $sRv .= $oRv;
+                $this->_oDb->setEventProcessed($aEvent['id']);
+            }
+        }
+        
+        return $sRv;
+    }
+    
+    public function serviceHandleActionNonView()
+    {
+       //for some other actions fex cron - not implemented
+    }
+    
+    public function addEvent($sAction, $iObjectId, $sModule, $sEvent, $iProfileId)
+    {
+        $this->_oDb->addEvent($sAction, $iObjectId, $sModule, $sEvent, $iProfileId);
+    }
+    
+    public function initPopupByEvent($iObjectId, $sModule, $sEvent, $iProfileId)
+    {
+        $this->addEvent('view', $iObjectId, $sModule, $sEvent, $iProfileId);
+    }
+    
+    public function processPopupOnEvent($aEvent)
+    {
+        $sRv = '';
+        $sDefaultEvent = getParam('bx_attendant_on_profile_event_list');
+        $oProfile = BxDolProfile::getInstance($aEvent['profile_id']);
+        $oAccount = $oProfile ? $oProfile->getAccountObject() : null;
+        $bNeedRaiseEvent = false;
+        if ($aEvent['event'] == 'add' && $aEvent['module'] == 'profile'){
+            if (getParam('bx_attendant_on_profile_creation_modules') != '' && ($sDefaultEvent == BX_ATTENDANT_ON_PROFILE_CREATION_EVENT_AFTER_REGISTRATION || ($sDefaultEvent == BX_ATTENDANT_ON_PROFILE_CREATION_EVENT_AFTER_CONFIRMATION  && $oAccount != null &&  $oAccount->isConfirmed()))){
+                if ($oProfile->getModule() != 'system'){
+                    $bNeedRaiseEvent = true;
+                }
+            }
+        }
+        else{
+            bx_alert('bx_attendant', 'before_show_popup', bx_get_logged_profile_id(), 0, ['module' => $aEvent['module'], 'event' => $aEvent['event'], 'object_id' => $aEvent['object_id'], 'result' => &$bNeedRaiseEvent]);
+        }
+        if ($bNeedRaiseEvent)
+            return getParam('bx_attendant_on_profile_creation_modules').'<script>oBxAttendant.showPopup("' . $aEvent['module'] . '", "' . $aEvent['event'] . '", ' . $aEvent['object_id'] . ')</script>';
+        else
+            return false;
+    }
+}
+
+/** @} */

+ 119 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/source/classes/BxAttendantTemplate.php

@@ -0,0 +1,119 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import ('BxDolModuleTemplate');
+
+class BxAttendantTemplate extends BxBaseModGeneralTemplate
+{
+    var $sContainerId = 'oBxAttendantPopupWithRecommendedOnProfileAdd';
+    
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+    
+    public function init()
+    {
+        $this->addJs([
+                'main.js', 
+                'flickity/flickity.pkgd.min.js', 
+                'modules/base/general/js/|showcase.js'
+            ]
+        );
+        $this->addCss([
+                'main.css', 
+                BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flickity/|flickity.css'
+            ]
+        );
+        
+        return $this->getJsCode('main') . BxBaseFunctions::getInstance()->transBox($this->sContainerId, '', true, true);
+    }
+    
+    public function popup($aModuleData, $bManual)
+    {
+        $aVars = [];
+        
+        foreach ($aModuleData as $sModuleName => $sModuleData){            
+           $aVars[] = [
+               'html' => $sModuleData, 
+               'title' => $this->getStringValueByModuleOrDefault('_bx_attendant_popup_with_recommended_title_', $sModuleName) , 
+               'description' => $this->getStringValueByModuleOrDefault('_bx_attendant_popup_with_recommended_description_', $sModuleName)
+           ];
+        }
+        
+        if ($bManual || count($aVars) >0){
+            return $this->parseHtmlByName('popup_recommended.html', [
+                    'bx_if:data' => [
+                        'condition' => count($aVars) > 0,
+                        'content' => [
+                            'bx_repeat:items' => $aVars, 
+                            'button_text' => _t('_bx_attendant_popup_with_recommended_button_text')
+                        ]
+                    ],
+                    'bx_if:nodata' => [
+                        'condition' => count($aVars) == 0,
+                        'content' => [
+                        ]
+                    ]
+                ]
+            );
+        }
+        else{
+            return '';
+        }
+    }
+    
+    public function getJsCode($sType, $aParams = array(), $bWrap = true)
+    {
+        $sRedirectUrl = '';
+        switch (getParam('bx_attendant_on_profile_after_action_url')) {
+            case 'profile':
+                $sRedirectUrl = BxDolProfile::getInstance()->getUrl();
+                break;
+
+            case 'custom':
+                $sRedirectCustom = getParam('bx_attendant_on_profile_after_action_url_custom');
+                if($sRedirectCustom) {
+                    $sRedirectUrl = BxDolPermalinks::getInstance()->permalink($sRedirectCustom);
+
+                    if (false === strpos($sRedirectUrl, 'http://') && false === strpos($sRedirectUrl, 'https://'))
+                        $sRedirectUrl = BX_DOL_URL_ROOT . $sRedirectCustom;
+                }
+                break;
+                
+            case 'homepage':
+                $sRedirectUrl =  BX_DOL_URL_ROOT;  
+                break;
+        }
+        
+        $aParams = array_merge(array(
+            'sContainerId' => $this->sContainerId,
+            'sUrlAfterShow' => $sRedirectUrl
+        ), $aParams);
+        
+        return parent::getJsCode($sType, $aParams, $bWrap);
+    }
+
+    private function getStringValueByModuleOrDefault($sKey, $sModuleName)
+    {
+        $sFullKey = $sKey . $sModuleName;
+        $sValue = _t($sFullKey);
+        if ($sValue == $sFullKey){
+            $oModule = BxDolModule::getInstance($sModuleName);
+            if ($oModule)
+                $sValue =_t($sKey . 'default', $oModule->_aModule['title']);
+        }
+        return $sValue;
+    }
+    
+}
+
+/** @} */

+ 77 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/source/install/config.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_attendant',
+    'title' => 'Attendant',
+    'note' => 'Attendant module.',
+    'version' => '13.0.2',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/attendant/',
+    'home_uri' => 'attendant',
+
+    'db_prefix' => 'bx_attendant_',
+    'class_prefix' => 'BxAttendant',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Attendant',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 35 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/source/install/sql/enable.sql

@@ -0,0 +1,35 @@
+SET @sName = 'bx_attendant';
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT IFNULL(MAX(`order`), 0) + 1 FROM `sys_options_types` WHERE `group` = 'modules');
+
+INSERT INTO `sys_options_types` (`group`, `name`, `caption`, `icon`, `order`) 
+VALUES('modules', @sName, '_bx_attendant_adm_stg_cpt_type', 'bx_attendant@modules/boonex/attendant/|std-icon.svg', IF(ISNULL(@iTypeOrder), 1, @iTypeOrder + 1));
+
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `hidden`, `order`) VALUES(@iTypeId,  'bx_attendant_on_profile_creation', '_bx_attendant_adm_stg_cpt_category_on_profile_creation', 0, 2);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_params`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_attendant_on_profile_creation_modules', '_bx_attendant_adm_stg_on_profile_creation_modules_list', '', 'list', 'a:2:{s:6:"module";s:12:"bx_attendant";s:6:"method";s:19:"get_profile_modules";}', '', '', '', 1),
+(@iCategoryId, 'bx_attendant_on_profile_event_list', '_bx_attendant_adm_stg_on_profile_creation_event_list', 'confirmation', 'select', 'a:2:{s:6:"module";s:12:"bx_attendant";s:6:"method";s:40:"get_popup_with_recommended_on_event_show";}', '', '', '', 2),
+(@iCategoryId, 'bx_attendant_on_profile_after_action_url', '_bx_attendant_adm_stg_on_profile_after_action_url', '', 'select', 'a:2:{s:6:"module";s:12:"bx_attendant";s:6:"method";s:31:"get_options_redirect_after_show";}', '', '', '', 3),
+(@iCategoryId, 'bx_attendant_on_profile_after_action_url_custom', '_bx_attendant_adm_stg_on_profile_after_action_url_custom', '', 'digit', '', '', '', '', 4);
+
+-- INJECTION
+INSERT INTO `sys_injections`(`name`, `page_index`, `key`, `type`, `data`, `replace`, `active`) VALUES
+(@sName, 0, 'injection_footer', 'service', 'a:2:{s:6:"module";s:12:"bx_attendant";s:6:"method";s:18:"handle_action_view";}', '0', '1');
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxAttendantAlertsResponse', 'modules/boonex/attendant/classes/BxAttendantAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('profile', 'add', @iHandler);
+
+-- MENU: notifications
+SET @iMIOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name` = 'sys_account_notifications' AND `order` < 9999);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', @sName, 'notifications-attendant', '_bx_attendant_menu_item_title_system_attendant', '_bx_attendant_menu_item_title_attendant', 'javascript:', 'oBxAttendant.showPopup(1)', '', 'fab buffer', '', '', 2147483646, 1, 0, @iMIOrder + 1);

+ 75 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/source/js/main.js

@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxAttendant(oOptions) {
+    this._sContainerId = oOptions.sContainerId == undefined ? 'oBxAttendant' : oOptions.sContainerId;
+    this._sUrlAfterShow = oOptions.sUrlAfterShow == undefined ? '' : oOptions.sUrlAfterShow;
+    this._sActionsUri = oOptions.sActionUri;
+    var $this = this;
+}
+
+BxAttendant.prototype.showPopup = function (bManual = 0, sModule = 'default', sEvent = 'default', sObject = 0) {
+    var $this = this;
+    
+    $.get($this._sActionsUri + 'RecomendedPopup/' + sModule + '/' + sEvent + '/' + sObject + '/' + bManual + '/', function (sData) {
+        if (sData != ''){
+            oData = $.parseJSON(sData);
+            if (oData.redirect){
+                window.location = oData.redirect;
+            }
+            else{
+                $(window).dolPopupAjax({
+                    url: $this._sActionsUri + 'RecomendedPopup/' + sModule + '/' + sEvent + '/' + sObject + '/' + bManual + '/',
+                    closeOnOuterClick: true,
+                    removeOnClose: true,
+                    onLoad: function(sPopupSelector){
+                        $(sPopupSelector + ' .bx-pwropa-item-container').hide().first().show();
+                            $this.reInitFlickity(sPopupSelector);
+                            $(sPopupSelector + ' .bx-pwropa-button').click(function () {
+                                $oCurr = $(sPopupSelector + ' .bx-pwropa-item-container:visible').hide();
+                                $oNext = $oCurr.next(); 
+                                $oNext.show();
+                                $this.reInitFlickity(sPopupSelector);
+                                if ($oNext.length == 0) {
+                                    $(sPopupSelector).dolPopupHide();
+                                    if ($this._sUrlAfterShow != '') {
+                                        location.href = $this._sUrlAfterShow;
+                                    }
+                                }
+                            });
+
+                    }
+                });
+            }
+        }
+    });
+}
+
+BxAttendant.prototype.reInitFlickity = function (sPopupSelector) {
+    var $this = this;
+    $(sPopupSelector + ' .bx-pwropa-item-container:visible .bx-base-unit-showcase-wrapper').flickity({
+        cellSelector: '.bx-base-unit-showcase',
+        cellAlign: 'left',
+        pageDots: false,
+        imagesLoaded: true
+    });
+    $('#' + $this._sContainerId)._dolPopupSetPosition();
+}
+
+BxAttendant.prototype.onActionComplete = function (data, e) {
+    if (data.err == false) {
+        var $e = $(e);
+        $e.hide();
+    }
+}
+
+function bx_attendant_conn_action(e, sObj, sAction, iContentId, bConfirm, fOnComplete) {
+    return bx_conn_action(e, sObj, sAction, iContentId, bConfirm, oBxAttendant.onActionComplete)
+}

+ 22 - 0
modules/boonex/attendant/updates/13.0.1_13.0.2/source/template/popup_recommended.html

@@ -0,0 +1,22 @@
+<div class="bx-def-page-width bx-pwropa-container bx-def-padding bx-page-block-container">
+    <bx_if:data>
+        <div class="bx-def-margin-bottom">
+            <bx_repeat:items>
+                <div class="bx-pwropa-item-container">
+                    <div class="bx-db-title bx-def-font-h2">__title__</div>
+                    <div class="bx-tl-content bx-def-margin-bottom">__description__</div>
+                    __html__
+                </div>
+            </bx_repeat:items>
+        </div>
+        <div class="bx-pwropa-button-container">
+            <a class="bx-btn bx-btn-small bx-pwropa-button">__button_text__</a>
+        </div>
+    </bx_if:data>
+    <bx_if:nodata>
+        <div class="bx-pwropa-item-container bx-pwropa-item-container-no-data">
+            <div class="bx-db-title bx-def-font-h2"><bx_text:_bx_attendant_popup_with_recommended_title_no_data /></div>
+            <div class="bx-tl-content bx-def-margin-bottom"><bx_text:_bx_attendant_popup_with_recommended_description_no_data /></div>
+        </div>
+    </bx_if:nodata>
+</div>

+ 51 - 0
modules/boonex/credits/updates/13.0.2_13.0.3/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Credits',
+    'version_from' => '13.0.2',
+    'version_to' => '13.0.3',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/credits/updates/update_13.0.2_13.0.3/',
+    'home_uri' => 'credits_update_1302_1303',
+
+    'module_dir' => 'boonex/credits/',
+    'module_uri' => 'credits',
+
+    'db_prefix' => 'bx_credits_',
+    'class_prefix' => 'BxCredits',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Credits',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/credits/updates/13.0.2_13.0.3/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxCreditsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 1096 - 0
modules/boonex/credits/updates/13.0.2_13.0.3/source/classes/BxCreditsModule.php

@@ -0,0 +1,1096 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Credits Credits
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+define('BX_CREDITS_TRANSFER_TYPE_PURCHASE', 'purchase');
+define('BX_CREDITS_TRANSFER_TYPE_CHECKOUT', 'checkout');
+define('BX_CREDITS_TRANSFER_TYPE_CANCELLATION', 'cancellation');
+define('BX_CREDITS_TRANSFER_TYPE_GRANT', 'grant');
+define('BX_CREDITS_TRANSFER_TYPE_SEND', 'send');
+define('BX_CREDITS_TRANSFER_TYPE_WITHDRAW', 'withdraw');
+define('BX_CREDITS_TRANSFER_TYPE_SERVICE', 'service');
+
+define('BX_CREDITS_DIRECTION_IN', 'in');
+define('BX_CREDITS_DIRECTION_OUT', 'out');
+
+define('BX_CREDITS_ORDER_TYPE_SINGLE', 'single'); //--- one-time payment
+define('BX_CREDITS_ORDER_TYPE_RECURRING', 'recurring'); //--- recurring payment (subscription)
+
+
+class BxCreditsModule extends BxBaseModGeneralModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    public function actionGetProfiles()
+    {
+        $sTerm = bx_get('term');
+
+        $a = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
+
+        echoJson($a);
+    }
+
+    public function actionCheckBundleName()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$sName = bx_process_input(bx_get('name'));
+    	if(empty($sName))
+            return echoJson(array());
+
+        $sResult = '';
+
+        $iId = (int)bx_get('id');
+        if(!empty($iId)) {
+            $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iId)); 
+            if(strcmp($sName, $aBundle[$CNF['FIELD_NAME']]) == 0) 
+                $sResult = $sName;
+        }
+
+    	echoJson(array(
+            'name' => !empty($sResult) ? $sResult : $this->_oConfig->getBundleName($sName)
+    	));
+    }
+
+    public function actionCheckout()
+    {
+        $iBuyerId = bx_get_logged_profile_id();
+        if(!$iBuyerId)
+            return echoJson(array('code' => 1, 'msg' => _t('_bx_credits_err_unknown_buyer')));
+
+        $aData = $this->_oConfig->getCheckoutData();
+        if(empty($aData) || !is_array($aData))
+            return echoJson(array('code' => 2, 'msg' => _t('_bx_credits_err_incorrect_data')));
+
+        $iSellerId = (int)$aData['seller'];
+        $fAmount = (float)$aData['amount'];
+
+        $fBalance = (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iBuyerId));
+        if($fAmount > $fBalance)
+            return echoJson(array('code' => 3, 'msg' => _t('_bx_credits_err_low_balance')));
+
+        $sOrder = $this->_oConfig->getOrder();
+        $sInfo = '_bx_credits_txt_history_info_checkout';
+        $sData = serialize(array(
+            'conversion' => $this->_oConfig->getConversionRateUse(),
+            'precision' => $this->_oConfig->getPrecision()
+        ));
+
+        $this->updateProfileBalance($iBuyerId, $iSellerId, -$fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo, $sData);
+        $this->updateProfileBalance($iSellerId, $iBuyerId, $fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo, $sData);
+
+        bx_alert($this->getName(), 'checkout', 0, false, array(
+            'seller' => $iSellerId,
+            'buyer' => $iBuyerId,
+            'amount' => $fAmount, 
+            'order' => $sOrder
+        ));
+
+        return echoJson(array(
+            'code' => 0,
+            'redirect' => bx_append_url_params($aData['return_data_url'], array('o' => $sOrder, 'c' => $aData['custom']))
+        ));
+    }
+
+    public function actionSubscribe()
+    {
+        $iBuyerId = bx_get_logged_profile_id();
+        if(!$iBuyerId)
+            return echoJson(array('code' => 1, 'msg' => _t('_bx_credits_err_unknown_buyer')));
+
+        $aData = $this->_oConfig->getCheckoutData();
+        if(empty($aData) || !is_array($aData))
+            return echoJson(array('code' => 2, 'msg' => _t('_bx_credits_err_incorrect_data')));
+
+        $iSellerId = (int)$aData['seller'];
+        $fAmount = (float)$aData['amount'];
+
+        $fBalance = (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iBuyerId));
+        if($fAmount > $fBalance)
+            return echoJson(array('code' => 3, 'msg' => _t('_bx_credits_err_low_balance')));
+
+        $sUnique = $this->_oConfig->getOrder(9);
+        $sCustomer = 'bx_cus_' . $sUnique;
+        $sSubscription = 'bx_sub_' . $sUnique;
+
+        bx_alert($this->getName(), 'subscribe', 0, false, array(
+            'seller' => $iSellerId,
+            'buyer' => $iBuyerId,
+            'amount' => $fAmount, 
+            'trial' => $aData['trial'],
+            'customer' => $sCustomer,
+            'subscription' => $sSubscription
+        ));
+
+        return echoJson(array(
+            'code' => 0,
+            'redirect' => bx_append_url_params($aData['return_data_url'], array(
+                'cs' => $sCustomer, 
+                'sb' => $sSubscription,
+                'tr' => $aData['trial'],
+                'c' => $aData['custom']
+            ))
+        ));
+    }
+
+    public function serviceGetSafeServices()
+    {
+        return array (
+            'GetBlockBundles' => '',
+            'GetBlockOrders' => '',
+            'GetBlockHistory' => '',
+        );
+    }
+
+    public function serviceGetCheckoutUrl()
+    {
+        return $this->_oConfig->getCheckoutUrl();
+    }
+
+    public function serviceValidateCheckout($iSeller, $iBuyer, $fAmount, $sOrder)
+    {
+        $fAmount = (float)$fAmount;
+
+        $aOut = $this->_oDb->getHistory(array('type' => 'row_by', 'by' => array('first_pid' => $iBuyer, 'direction' => BX_CREDITS_DIRECTION_OUT, 'order' => $sOrder)));
+        if(empty($aOut) || !is_array($aOut) || (int)$aOut['second_pid'] != (int)$iSeller)
+            return false;
+        
+        $aDataOut = unserialize($aOut['data']);
+        if($this->_oConfig->convertM2C($fAmount, $aDataOut['conversion'], $aDataOut['precision']) != (float)$aOut['amount'])
+            return false;
+
+        $aIn = $this->_oDb->getHistory(array('type' => 'row_by', 'by' => array('first_pid' => $iSeller, 'direction' => BX_CREDITS_DIRECTION_IN, 'order' => $sOrder)));
+        if(empty($aIn) || !is_array($aIn) || (int)$aIn['second_pid'] != (int)$iBuyer)
+            return false;
+
+        $aDataIn = unserialize($aIn['data']);
+        if($this->_oConfig->convertM2C($fAmount, $aDataIn['conversion'], $aDataIn['precision']) != (float)$aIn['amount'])
+            return false;
+
+        return true;
+    }
+
+    public function serviceGetBlockCheckout()
+    {
+        $oBuyer = BxDolProfile::getInstance();
+        if(!$oBuyer)
+            return MsgBox(_t('_bx_credits_err_unknown_buyer'));
+        
+        $iSeller = (int)bx_get('seller');
+        $oSeller = BxDolProfile::getInstance($iSeller);
+        if(!$oSeller)
+            return MsgBox(_t('_bx_credits_err_unknown_seller'));
+
+        $fAmountM = (float)bx_get('amount');
+        $fAmountC = $this->_oConfig->convertM2C($fAmountM);
+
+        $aData = array(
+            'seller' => $iSeller,
+            'currency' => array(
+                'code' => bx_process_input(bx_get('currency_code')),
+                'sign' => bx_process_input(bx_get('currency_sign')),
+            ),
+            'amountm' => $fAmountM,
+            'amountc' => $fAmountC
+        );
+
+        $iItemsCount = (int)bx_get('items_count');
+        for($i = 0; $i < $iItemsCount; $i++) {
+            $aData['items'][] = array(
+                'title' => bx_process_input(bx_get('item_title_' . $i)),
+                'quantity' => (int)bx_get('item_quantity_' . $i)
+            );
+        }
+
+        $this->_oConfig->setCheckoutData(array(
+            'seller' => $iSeller,
+            'amount' => $fAmountC,
+            'custom' => bx_process_input(bx_get('custom')),
+            'return_data_url' => bx_process_input(bx_get('return_data_url')),
+        ));
+        return $this->_oTemplate->getBlockCheckout($oBuyer, $oSeller, $aData);
+    }
+
+    public function serviceGetPopupSubscribe($aData)
+    {
+        $oBuyer = BxDolProfile::getInstance();
+        if(!$oBuyer)
+            return array('msg' => _t('_bx_credits_err_unknown_buyer'));
+
+        $iSeller = (int)$aData['seller'];
+        $oSeller = BxDolProfile::getInstance($iSeller);
+        if(!$oSeller)
+            return array('msg' => _t('_bx_credits_err_unknown_seller'));
+
+        $fAmountM = (float)$aData['amount'];
+        $fAmountC = $this->_oConfig->convertM2C($fAmountM);
+
+        $aData = array_merge($aData, array(
+            'amountm' => $fAmountM,
+            'amountc' => $fAmountC
+        ));
+
+        $this->_oConfig->setCheckoutData(array(
+            'seller' => $iSeller,
+            'amount' => $fAmountC,
+            'trial' => (int)$aData['trial'] > 0,
+            'custom' => bx_process_input($aData['custom']),
+            'return_data_url' => bx_process_input($aData['return_data_url']),
+        ));
+        return $this->_oTemplate->getPopupSubscribe($oBuyer, $oSeller, $aData);
+    }
+
+    public function serviceGetMenuItemAddonAmount()
+    {
+        $iProfileId = bx_get_logged_profile_id();
+        if(!$iProfileId)
+            return '';
+
+        return array(
+            'unit' => $this->_oTemplate->getUnit(), 
+            'value' => $this->convertC2S($this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId)), false)
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-page_blocks Page Blocks
+     * @subsubsection bx_credits-get_block_bundles get_block_bundles
+     * 
+     * @code bx_srv('bx_credits', 'get_block_bundles'); @endcode
+     * 
+     * Get page block with bundles
+     * 
+     * @see BxCreditsModule::serviceGetBlockBundles
+     */
+    /** 
+     * @ref bx_credits-get_block_bundles "get_block_bundles"
+     */
+    public function serviceGetBlockBundles()
+    {
+        return $this->_oTemplate->getBlockBundles();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-page_blocks Page Blocks
+     * @subsubsection bx_credits-get_block_orders_note get_block_orders_note
+     * 
+     * @code bx_srv('bx_credits', 'get_block_orders_note', [...]); @endcode
+     * 
+     * Get page block with a notice for orders usage.
+     *
+     * @return HTML string with block content to display on the site.
+     * 
+     * @see BxCreditsModule::serviceBlockLicensesNote
+     */
+    /** 
+     * @ref bx_credits-get_block_orders_note "get_block_orders_note"
+     */
+    public function serviceGetBlockOrdersNote()
+    {
+        return MsgBox(_t('_bx_credits_page_block_content_orders_common_note'));
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-page_blocks Page Blocks
+     * @subsubsection bx_credits-block_orders get_block_orders
+     * 
+     * @code bx_srv('bx_credits', 'get_block_orders', [...]); @endcode
+     * 
+     * Get page block with a list of orders purchased by currently logged member.
+     *
+     * @return an array describing a block to display on the site or false if there is no enough input data. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxCreditsModule::serviceBlockLicenses
+     */
+    /** 
+     * @ref bx_credits-get_block_orders "get_block_orders"
+     */
+    public function serviceGetBlockOrders($sType = 'common') 
+    {
+        return $this->_getBlockOrders($sType);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-page_blocks Page Blocks
+     * @subsubsection bx_credits-get_block_history get_block_history
+     * 
+     * @code bx_srv('bx_credits', 'get_block_history', [...]); @endcode
+     * 
+     * Get page block with a list of all changes with credits.
+     *
+     * @return an array describing a block to display on the site or false if there is no enough input data. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxCreditsModule::serviceGetBlockHistory
+     */
+    /** 
+     * @ref bx_credits-get_block_history "get_block_history"
+     */
+    public function serviceGetBlockHistory($sType = 'common') 
+    {
+        return $this->_getBlockHistory($sType);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-get_payment_data get_payment_data
+     * 
+     * @code bx_srv('bx_credits', 'get_payment_data', [...]); @endcode
+     * 
+     * Get an array with module's description. Is needed for payments processing module.
+     * 
+     * @return an array with module's description.
+     * 
+     * @see BxCreditsModule::serviceGetPaymentData
+     */
+    /** 
+     * @ref bx_credits-get_payment_data "get_payment_data"
+     */
+    public function serviceGetPaymentData()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oPermalink = BxDolPermalinks::getInstance();
+
+        $aResult = $this->_aModule;
+        $aResult['url_browse_order_common'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_ORDERS_COMMON'], array('filter' => '{order}'));
+        $aResult['url_browse_order_administration'] = BX_DOL_URL_ROOT . $oPermalink->permalink($CNF['URL_ORDERS_ADMINISTRATION'], array('filter' => '{order}'));
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-get_cart_item get_cart_item
+     * 
+     * @code bx_srv('bx_credits', 'get_cart_item', [...]); @endcode
+     * 
+     * Get an array with prodict's description. Is used in Shopping Cart in payments processing module.
+     * 
+     * @param $iItemId product's ID.
+     * @return an array with prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxCreditsModule::serviceGetCartItem
+     */
+    /** 
+     * @ref bx_credits-get_cart_item "get_cart_item"
+     */
+    public function serviceGetCartItem($iItemId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        if(!$iItemId)
+            return array();
+
+        $aItem = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
+        if(empty($aItem) || !is_array($aItem))
+            return array();
+
+        return array (
+            'id' => $aItem[$CNF['FIELD_ID']],
+            'author_id' => $this->_oConfig->getAuthor(),
+            'name' => $aItem[$CNF['FIELD_NAME']],
+            'title' => _t($aItem[$CNF['FIELD_TITLE']]),
+            'description' => $this->_oConfig->getBundleDescription($aItem),
+            'url' => $this->_oConfig->getBundleUrl($aItem),
+            'price_single' => $aItem[$CNF['FIELD_PRICE']],
+            'price_recurring' => '',
+            'period_recurring' => 1,
+            'period_unit_recurring' => '',
+            'trial_recurring' => ''
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-get_cart_items get_cart_items
+     * 
+     * @code bx_srv('bx_credits', 'get_cart_items', [...]); @endcode
+     * 
+     * Get an array with prodicts' descriptions by seller. Is used in Manual Order Processing in payments processing module.
+     * 
+     * @param $iSellerId seller ID.
+     * @return an array with prodicts' descriptions. Empty array is returned if something is wrong or seller doesn't have any products.
+     * 
+     * @see BxCreditsModule::serviceGetCartItems
+     */
+    /** 
+     * @ref bx_credits-get_cart_items "get_cart_items"
+     */
+    public function serviceGetCartItems($iSellerId)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $iAuthorId = $this->_oConfig->getAuthor();
+        if($iSellerId != $iAuthorId && !BxDolAcl::getInstance()->isMemberLevelInSet([MEMBERSHIP_ID_ADMINISTRATOR], $iSellerId))
+            return array();
+
+        $aItems = $this->_oDb->getBundle(array('type' => 'all', 'active' => 1));
+
+        $aResult = array();
+        foreach($aItems as $aItem)
+            $aResult[] = array(
+                'id' => $aItem[$CNF['FIELD_ID']],
+                'author_id' => $iAuthorId,
+                'name' => $aItem[$CNF['FIELD_NAME']],
+                'title' => _t($aItem[$CNF['FIELD_TITLE']]),
+                'description' => $this->_oConfig->getBundleDescription($aItem),
+                'url' => $this->_oConfig->getBundleUrl($aItem),
+                'price_single' => $aItem[$CNF['FIELD_PRICE']],
+                'price_recurring' => '',
+                'period_recurring' => 1,
+                'period_unit_recurring' => '',
+                'trial_recurring' => ''
+            );
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-register_cart_item register_cart_item
+     * 
+     * @code bx_srv('bx_credits', 'register_cart_item', [...]); @endcode
+     * 
+     * Register a processed single time payment inside the Credits module. Is called with payment processing module after the payment was registered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxCreditsModule::serviceRegisterCartItem
+     */
+    /** 
+     * @ref bx_credits-register_cart_item "register_cart_item"
+     */
+    public function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_SINGLE);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-register_subscription_item register_subscription_item
+     * 
+     * @code bx_srv('bx_credits', 'register_subscription_item', [...]); @endcode
+     * 
+     * Register a processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was registered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxCreditsModule::serviceRegisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_credits-register_subscription_item "register_subscription_item"
+     */
+    public function serviceRegisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        return $this->_serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_RECURRING);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-reregister_cart_item reregister_cart_item
+     * 
+     * @code bx_srv('bx_credits', 'reregister_cart_item', [...]); @endcode
+     * 
+     * Reregister a single time payment inside the Credits module. Is called with payment processing module after the payment was reregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemIdOld old item ID.
+     * @param $iItemIdNew new item ID.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return an array with purchased prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxCreditsModule::serviceReregisterCartItem
+     */
+    /** 
+     * @ref bx_credits-reregister_cart_item "reregister_cart_item"
+     */
+    public function serviceReregisterCartItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
+    {
+        return array();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-reregister_subscription_item reregister_subscription_item
+     * 
+     * @code bx_srv('bx_credits', 'reregister_subscription_item', [...]); @endcode
+     * 
+     * Reregister a subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was reregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemIdOld old item ID.
+     * @param $iItemIdNew new item ID.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return an array with subscribed prodict's description. Empty array is returned if something is wrong.
+     * 
+     * @see BxCreditsModule::serviceReregisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_credits-reregister_subscription_item "reregister_subscription_item"
+     */
+    public function serviceReregisterSubscriptionItem($iClientId, $iSellerId, $iItemIdOld, $iItemIdNew, $sOrder)
+    {
+        return array();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-unregister_cart_item unregister_cart_item
+     * 
+     * @code bx_srv('bx_credits', 'unregister_cart_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed single time payment inside the Credits module. Is called with payment processing module after the payment was unregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return boolean value determining where the payment was unregistered or not.
+     * 
+     * @see BxCreditsModule::serviceUnregisterCartItem
+     */
+    /** 
+     * @ref bx_credits-unregister_cart_item "unregister_cart_item"
+     */
+    public function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+        return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_SINGLE);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-unregister_subscription_item unregister_subscription_item
+     * 
+     * @code bx_srv('bx_credits', 'unregister_subscription_item', [...]); @endcode
+     * 
+     * Unregister an earlier processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was unregistered there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @param $sLicense license number genereted with payment processing module for internal usage
+     * @return boolean value determining where the subscription was unregistered or not.
+     * 
+     * @see BxCreditsModule::serviceUnregisterSubscriptionItem
+     */
+    /** 
+     * @ref bx_credits-unregister_subscription_item "unregister_subscription_item"
+     */
+    public function serviceUnregisterSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense)
+    {
+    	return $this->_serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, BX_CREDITS_ORDER_TYPE_RECURRING); 
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_credits Credits
+     * @subsection bx_credits-payments Payments
+     * @subsubsection bx_credits-cancel_subscription_item cancel_subscription_item
+     * 
+     * @code bx_srv('bx_credits', 'cancel_subscription_item', [...]); @endcode
+     * 
+     * Cancel an earlier processed subscription (recurring payment) inside the Credits module. Is called with payment processing module after the subscription was canceled there.
+     * 
+     * @param $iClientId client ID.
+     * @param $iSellerId seller ID
+     * @param $iItemId item ID.
+     * @param $iItemCount the number of purchased items.
+     * @param $sOrder order number received from payment provider (PayPal, Stripe, etc)
+     * @return boolean value determining where the subscription was canceled or not.
+     * 
+     * @see BxCreditsModule::serviceCancelSubscriptionItem
+     */
+    /** 
+     * @ref bx_credits-cancel_subscription_item "cancel_subscription_item"
+     */
+    public function serviceCancelSubscriptionItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder)
+    {
+    	return true;
+    }
+
+    public function serviceGetProfileBalance($iProfileId = 0)
+    {
+        return $this->getProfileBalance($iProfileId);
+    }
+
+    public function serviceUpdateProfileBalance($iFirstPid, $fAmount, $iSecondPid = 0, $sOrder = '', $sInfo = '')
+    {
+        if(empty($sInfo))
+            $sInfo = '_bx_credits_txt_history_info_service';
+
+        return $this->updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, BX_CREDITS_TRANSFER_TYPE_SERVICE, $sOrder, $sInfo);
+    }
+    
+    public function serviceMakePayment($iBuyerPid, $fAmount, $iSellerPid, $sOrder = '')
+    {
+        $sInfo = '_bx_credits_txt_history_info_checkout';
+
+        if(!$this->updateProfileBalance($iBuyerPid, $iSellerPid, -$fAmount, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sOrder, $sInfo))
+            return false;
+
+        if(!$this->updateProfileBalance($iSellerPid, $iBuyerPid, $fAmount, $sOrder, BX_CREDITS_TRANSFER_TYPE_CHECKOUT, $sInfo)) {
+            $this->updateProfileBalance($iBuyerPid, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_CANCELLATION, $sOrder, '_bx_credits_txt_history_info_cancellation');
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Delete all content by profile 
+     * @param $iProfileId profile id 
+     * @return number of deleted items
+     */
+    public function serviceDeleteEntitiesByAuthor ($iProfileId)
+    {
+        $this->_oDb->deleteProfile(array('id' => $iProfileId));
+        $this->_oDb->deleteHistory(array('first_pid' => $iProfileId));
+    }
+
+
+    /*
+     * Common methods
+     */
+    public function convertC2S($fCredits, $bWithUnit = true)
+    {
+        $sResult = '';
+        if($bWithUnit)
+            $sResult .= $this->_oTemplate->getUnit();
+
+        $iPrecision = $this->_oConfig->getPrecision();
+        $sResult .= sprintf("%01." . $iPrecision . "f", round((float)$fCredits, $iPrecision));
+
+        return $sResult;
+    }
+
+    public function getProfileBalance($iProfileId = 0)
+    {
+        if(empty($iProfileId))
+            $iProfileId = bx_get_logged_profile_id();
+
+        if(empty($iProfileId))
+            return 0;
+
+        return (float)$this->_oDb->getProfile(array('type' => 'balance', 'id' => $iProfileId));
+    }
+
+    public function getProfileBalanceCleared($iProfileId = 0)
+    {
+        if(empty($iProfileId))
+            $iProfileId = bx_get_logged_profile_id();
+
+        if(empty($iProfileId))
+            return 0;
+
+        $fCleared = (float)$this->_oDb->getHistory(['type' => 'cleared', 'profile' => $iProfileId]);
+        $fSpent = (float)$this->_oDb->getHistory(['type' => 'spent', 'profile' => $iProfileId]);
+
+        return $fCleared > $fSpent ? $fCleared - $fSpent : 0;
+    }
+
+    public function updateProfileBalance($iFirstPid, $iSecondPid, $fAmount, $sType, $sOrder = '', $sInfo = '', $sData = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($sOrder))
+            $sOrder = $this->_oConfig->getOrder();
+
+        if(empty($sData))
+            $sData = serialize(array(
+                'conversion' => $this->_oConfig->getConversionRateUse(),
+                'precision' => $this->_oConfig->getPrecision()
+            ));
+
+        if(!$this->_oDb->updateProfileBalance($iFirstPid, $fAmount))
+            return false;
+
+        $fAmountAbs = abs($fAmount);
+        $sDirection = $fAmount > 0 ? BX_CREDITS_DIRECTION_IN : BX_CREDITS_DIRECTION_OUT;
+
+        $iHistoryId = $this->_oDb->insertHistory([
+            'first_pid' => $iFirstPid,
+            'second_pid' => $iSecondPid,
+            'amount' => $fAmountAbs,
+            'type' => $sType,
+            'direction' => $sDirection,
+            'order' => $sOrder,
+            'data' => $sData,
+            'info' => $sInfo,
+            'date' => time()
+        ]);
+
+        if(!$iHistoryId)
+            return false;
+
+        bx_alert($this->getName(), 'update_balance', 0, false, array(
+            'first_pid' => $iFirstPid,
+            'second_pid' => $iSecondPid,
+            'amount' => $fAmountAbs,
+            'type' => $sType,
+            'direction' => $sDirection,
+            'order' => $sOrder,
+        ));
+
+        $oSecondProfile = BxDolProfile::getInstanceMagic($iSecondPid);
+        sendMailTemplate($CNF['ETEMPLATE_' . strtoupper($sDirection)], 0, $iFirstPid, array(
+            'second_profile_name' => $oSecondProfile->getDisplayName(),
+            'amount' => $fAmountAbs,
+        ));
+
+        return $iHistoryId;
+    }
+
+    public function processGrant($iUserId, $iProfileId, $fAmount, $sMessage = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if(!$oProfile)
+            return ['code' => 2, 'msg' => '_bx_credits_err_profile_not_found'];
+
+        $sInfo = '_bx_credits_txt_history_info_grant';
+        $iHistoryId = $this->updateProfileBalance($iProfileId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_GRANT, '', $sInfo);
+        if(!$iHistoryId)
+            return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
+
+        sendMailTemplate($CNF['ETEMPLATE_GRANTED'], 0, $iProfileId, [
+            'amount' => $fAmount,
+            'message' => $sMessage
+        ]);
+
+        bx_alert($this->getName(), 'granted', 0, false, [
+            'profile' => $iProfileId,
+            'amount' => $fAmount,
+        ]);
+
+        return ['code' => 0, 'id' => $iHistoryId];
+    }
+
+    public function processSend($iUserId, $iProfileId, $fAmount, $sMessage = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $fAmountAvail = $this->getProfileBalance($iUserId);
+        if($fAmount > $fAmountAvail)
+            return ['code' => 1, 'msg' => '_bx_credits_err_low_balance'];
+
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if(!$oProfile)
+            return ['code' => 2, 'msg' => '_bx_credits_err_profile_not_found'];
+
+        $sOrder = $this->_oConfig->getOrder();
+        $sInfo = !empty($sMessage) ? $sMessage : '_bx_credits_txt_history_info_send';
+
+        $iHistoryId = $this->updateProfileBalance($iUserId, $iProfileId, -$fAmount, BX_CREDITS_TRANSFER_TYPE_SEND, $sOrder, $sInfo);
+        if(!$iHistoryId)
+            return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
+
+        if(!$this->updateProfileBalance($iProfileId, $iUserId, $fAmount, BX_CREDITS_TRANSFER_TYPE_SEND, $sOrder, $sInfo)) {
+            $sInfo = '_bx_credits_txt_history_info_cancellation';
+            $iHistoryId = $this->updateProfileBalance($iUserId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_CANCELLATION, $sOrder, $sInfo);
+
+            return ['code' => 3, 'id' => $iHistoryId, 'msg' => '_bx_credits_err_cannot_update_balance'];
+        }
+
+        $oUser = BxDolProfile::getInstance($iUserId);
+        sendMailTemplate($CNF['ETEMPLATE_RECEIVED'], 0, $iProfileId, [
+            'performer_id' => $iUserId,
+            'performer_name' => $oUser->getDisplayName(),
+            'performer_link' => $oUser->getUrl(),
+            'amount' => $fAmount,
+            'order' => $sOrder,
+            'message' => $sMessage
+        ]);
+
+        bx_alert($this->getName(), 'sent', 0, $iUserId, [
+            'performer' => $iUserId,
+            'profile' => $iProfileId,
+            'amount' => $fAmount,
+            'order' => $sOrder,
+        ]);
+
+        return ['code' => 0, 'id' => $iHistoryId];
+    }
+
+    public function processWithdrawRequest($iUserId, $iProfileId, $fAmount, $sMessage = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($iProfileId))
+            $iProfileId = bx_get_logged_profile_id ();
+
+        if(empty($iProfileId))
+            return ['code' => 1, 'msg' => '_bx_credits_err_login_required'];
+
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if(!$oProfile)
+            return ['code' => 1, 'msg' => '_bx_credits_err_login_required'];
+
+        $fBalanceCleared = $this->getProfileBalanceCleared($iProfileId);
+        if($fAmount > $fBalanceCleared)
+            return ['code' => 2, 'msg' => '_bx_credits_err_low_balance'];
+
+        if($fAmount < ($iWithdrawMinimum = (int)getParam($CNF['PARAM_WITHDRAW_MINIMUM'])))
+            return ['code' => 3, 'msg' => _t('_bx_credits_err_withdraw_minimum', $iWithdrawMinimum)];
+
+        $fBalance = $this->getProfileBalance($iProfileId);
+        if(($fBalance - $fAmount) < ($iWithdrawRemaining = (int)getParam($CNF['PARAM_WITHDRAW_REMAINING'])))
+            return ['code' => 4, 'msg' => _t('_bx_credits_err_withdraw_remaining', $iWithdrawRemaining)];
+
+        $aResult = ['code' => 5, 'msg' => '_bx_credits_err_cannot_send'];
+
+        $fRate = $this->_oConfig->getConversionRateWithdraw();
+
+        $aTemplateVars = [
+            'profile_link' => $oProfile->getUrl(),
+            'profile_name' => $oProfile->getDisplayName(),
+            'amount' => $fAmount,
+            'rate' => $fRate,
+            'message' => $sMessage,
+            'confirm_url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_HISTORY_ADMINISTRATION'])
+        ];
+        $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($CNF['ETEMPLATE_WITHDRAW_REQUESTED'], $aTemplateVars);
+        if(!$aTemplate)
+            return $aResult;
+
+        $sEmail = $this->_oConfig->getWithdrawEmail();
+        if(!sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, [], BX_EMAIL_SYSTEM, 'html', false, [], true))
+            return $aResult;
+
+        bx_alert($this->getName(), 'withdraw_requested', 0, $iProfileId, [
+            'profile' => $iProfileId,
+            'amount' => $fAmount,
+            'rate' => $fRate
+        ]);
+
+        return ['code' => 0];
+    }
+
+    public function processWithdrawConfirm($iUserId, $iProfileId, $fAmount, $sMessage = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if(!$oProfile)
+            return ['code' => 1, 'msg' => '_bx_credits_err_profile_not_found'];
+
+        $fBalance = $this->getProfileBalance($iProfileId);
+        if($fAmount > $fBalance)
+            return ['code' => 2, 'msg' => '_bx_credits_err_low_balance'];
+
+        $sInfo = '_bx_credits_txt_history_info_withdraw';
+        $iHistoryId = $this->updateProfileBalance($iProfileId, 0, -$fAmount, BX_CREDITS_TRANSFER_TYPE_WITHDRAW, '', $sInfo);
+        if(!$iHistoryId)
+            return ['code' => 3, 'msg' => '_bx_credits_err_cannot_update_balance'];
+
+        sendMailTemplate($CNF['ETEMPLATE_WITHDRAW_SENT'], 0, $iProfileId, [
+            'amount' => $fAmount,
+            'message' => $sMessage
+        ]);
+
+        bx_alert($this->getName(), 'withdraw_sent', 0, $iUserId, [
+            'performer' => $iUserId,
+            'profile' => $iProfileId,
+            'amount' => $fAmount,
+        ]);
+
+        return ['code' => 0, 'id' => $iHistoryId];
+    }
+
+    public function processClearing()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aItems = $this->_oDb->getHistory(['type' => 'clearing', 'clearing' => $this->_oConfig->getWithdrawClearing()]);
+        if(empty($aItems) || !is_array($aItems))
+            return;
+
+        $iNow = time();
+        foreach($aItems as $aItem) {
+            $this->_oDb->updateHistory([$CNF['FIELD_H_CLEARED'] => $iNow], [$CNF['FIELD_H_ID'] => $aItem['id']]);
+
+            //TODO: Some action(s) related to clearing can be performed here.
+        }
+    }
+
+    /*
+     * Internal methods
+     */
+    protected function _serviceRegisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$aItem = $this->serviceGetCartItem($iItemId);
+        if(empty($aItem) || !is_array($aItem))
+            return array();
+
+        $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
+        if(empty($aBundle) || !is_array($aBundle))
+            return array();
+
+        $iTrial = 0;
+        $sDuration = '';
+        $sAction = 'register';
+        if($sType == BX_CREDITS_ORDER_TYPE_RECURRING && isset($CNF['FIELD_DURATION_RECURRING'], $CNF['FIELD_TRIAL_RECURRING'])) {
+            $iTrial = $aBundle[$CNF['FIELD_TRIAL_RECURRING']];
+            $sDuration = $aBundle[$CNF['FIELD_DURATION_RECURRING']];
+
+            if($this->_oDb->isOrderByPbo($iClientId, $iItemId, $sOrder))
+                $sAction = 'prolong';
+        }
+
+        if(!$this->_oDb->{$sAction . 'Order'}($iClientId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType, $sDuration, $iTrial))
+            return array();
+
+        $sInfo = '_bx_credits_txt_history_info_purchase';
+        $fAmount = ((float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']]) * $iItemCount;
+        if(!$this->updateProfileBalance($iClientId, 0, $fAmount, BX_CREDITS_TRANSFER_TYPE_PURCHASE, '', $sInfo))
+            return array();
+
+        bx_alert($this->getName(), 'order_' . $sAction, 0, false, array(
+            'profile_id' => $iClientId,
+            'bundle_id' => $iItemId,
+            'product_id' => $iItemId,   //--- Alias for 'bundle_id'
+            'count' => $iItemCount,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'type' => $sType,
+            'duration' => $sDuration,
+            'trial' => $iTrial
+        ));
+
+        $oClient = BxDolProfile::getInstanceMagic($iClientId);
+        $oSeller = BxDolProfile::getInstanceMagic($iSellerId);
+        $sSellerUrl = $oSeller->getUrl();
+        $sSellerName = $oSeller->getDisplayName();
+
+        sendMailTemplate($CNF['ETEMPLATE_PURCHASED'], 0, $iClientId, array(
+            'client_name' => $oClient->getDisplayName(),
+            'bundle_name' => $aBundle[$CNF['FIELD_NAME']],
+            'bundle_title' => _t($aBundle[$CNF['FIELD_TITLE']]),
+            'bundle_url' => $this->_oConfig->getBundleUrl($aBundle),
+            'vendor_url' => $sSellerUrl,
+            'vendor_name' => $sSellerName,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'notes' => _t('_bx_credits_txt_purchased_note', $sSellerUrl, $sSellerName),
+        ));
+
+        return $aItem;
+    }
+
+    protected function _serviceUnregisterItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrder, $sLicense, $sType)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aBundle = $this->_oDb->getBundle(array('type' => 'id', 'id' => $iItemId));
+        if(empty($aBundle) || !is_array($aBundle))
+            return false;
+
+        if(!$this->_oDb->unregisterOrder($iClientId, $iItemId, $sOrder, $sLicense, $sType))
+            return false;
+
+        $fAmount = (float)$aBundle[$CNF['FIELD_AMOUNT']] + (float)$aBundle[$CNF['FIELD_BONUS']];
+        $aProfile = $this->_oDb->getProfile(array('type' => 'id', 'id' => $iClientId));
+        if(!empty($aProfile) && is_array($aProfile))
+            $this->_oDb->updateProfile(array('balance' => (float)$aProfile['balance'] - $fAmount), array('id' => $aProfile['id']));
+
+        bx_alert($this->getName(), 'order_unregister', 0, false, array(
+            'profile_id' => $iClientId,
+            'bundle_id' => $iItemId,
+            'product_id' => $iItemId,   //--- Alias for 'bundle_id'
+            'count' => $iItemCount,
+            'order' => $sOrder,
+            'license' => $sLicense,
+            'type' => $sType,
+        ));
+
+        return true;
+    }
+
+    protected function _getBlockOrders($sType) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sGrid = $CNF['OBJECT_GRID_ORDERS_' . strtoupper($sType)];
+        $oGrid = BxDolGrid::getObjectInstance($sGrid);
+        if(!$oGrid)
+            return '';
+
+        return array(
+            'content' => $oGrid->getCode(),
+            'menu' => $CNF['OBJECT_MENU_MANAGE_SUBMENU']
+        );
+    }
+
+    protected function _getBlockHistory($sType) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sGrid = $CNF['OBJECT_GRID_HISTORY_' . strtoupper($sType)];
+        $oGrid = BxDolGrid::getObjectInstance($sGrid);
+        if(!$oGrid)
+            return '';
+
+        return array(
+            'content' => $oGrid->getCode(),
+            'menu' => $CNF['OBJECT_MENU_MANAGE_SUBMENU']
+        );
+    }
+}
+
+/** @} */

+ 77 - 0
modules/boonex/credits/updates/13.0.2_13.0.3/source/install/config.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Credits Credits
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_credits',
+    'title' => 'Credits',
+    'note' => 'Credits module.',
+    'version' => '13.0.3',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/credits/',
+    'home_uri' => 'credits',
+
+    'db_prefix' => 'bx_credits_',
+    'class_prefix' => 'BxCredits',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Credits',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(),
+
+);
+
+/** @} */

+ 51 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Decorous',
+    'version_from' => '13.0.4',
+    'version_to' => '13.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/decorous/updates/update_13.0.4_13.0.5/',
+    'home_uri' => 'decorous_update_1304_1305',
+
+    'module_dir' => 'boonex/decorous/',
+    'module_uri' => 'decorous',
+
+    'db_prefix' => 'bx_decorous_',
+    'class_prefix' => 'BxDecorous',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Decorous Template',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 26 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/install/installer.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxDecorousUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function update($aParams)
+    {
+        $aResult = parent::update($aParams);
+        if(!$aResult['result'])
+            return $aResult;
+
+        $oCacheUtilities = BxDolCacheUtilities::getInstance();
+        $oCacheUtilities->clear('css');
+        $oCacheUtilities->clear('template');
+
+        return $aResult;
+    }
+}

+ 929 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/css/default.less

@@ -0,0 +1,929 @@
+@import (reference) '../../../../../../../template/css/_mixins.less';
+
+.@{bx-root-class-name}.bx-def-font {
+    font-family:@bx-font-family;
+    font-weight:400; /* 26.13.13: prev val 300 */
+    .font-size(@bx-font-size-default);
+    color:@bx-font-color-default;
+}
+
+.@{bx-root-class-name}.bx-def-color-bg-page {
+    .background-color (@bx-color-page);
+}
+
+.@{bx-root-class-name}.bx-def-image-bg-page {
+    background-position: center center;
+    background-image: @bx-image-bg-page;
+    background-repeat: @bx-image-bg-page-repeat;
+    background-attachment: @bx-image-bg-page-attachment;
+    background-size: @bx-image-bg-page-size;
+}
+
+.@{bx-root-class-name} {
+    @import '../../../../../../../template/css/default.less';
+
+    /**
+     * Is used for inputs and buttons. They should have the same value 
+     * because Input and Button can be positioned in one line.
+     */
+    @base-input-box-sizing: border-box;
+
+
+    /* height */
+    .bx-header {
+        height: @bx-height-header !important;
+    }
+    .bx-main-content .bx-main-column.narrow .bx-menu-toolbar-padding,
+    .cd-main-content .content-wrapper {
+        padding-top: @bx-height-header;
+    }
+
+
+    /* content paddings */
+    .bx-content-padding-header {
+        padding: @bx-content-padding-header;
+    }
+    .bx-content-padding-footer {
+        padding: @bx-content-padding-footer;
+    }
+    .bx-content-padding-block {
+        padding: @bx-content-padding-block;
+    }
+
+
+    /* shadow */
+    .bx-shadow-header {
+        -webkit-box-shadow: @bx-shadow-header;
+        -moz-box-shadow: @bx-shadow-header;
+        box-shadow: @bx-shadow-header;
+    }
+    .bx-shadow-footer {
+        -webkit-box-shadow: @bx-shadow-footer;
+        -moz-box-shadow: @bx-shadow-footer;
+        box-shadow: @bx-shadow-footer;
+    }
+    .bx-shadow-block {
+        -webkit-box-shadow: @bx-shadow-block;
+        -moz-box-shadow: @bx-shadow-block;
+        box-shadow: @bx-shadow-block;
+    }
+    .bx-def-box {
+        -webkit-box-shadow: @bx-shadow-card;
+        -moz-box-shadow: @bx-shadow-card;
+        box-shadow: @bx-shadow-card;
+    }
+    .bx-def-box:hover {
+        -webkit-box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1);
+        -moz-box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1);
+        box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1);
+    }
+    .bx-popup-applied {
+        border-radius: @bx-border-radius-popup;
+        background-clip: padding-box;
+    }
+    .bx-popup-applied:not(.bx-popup-chain) .bx-popup,
+    .bx-popup-applied.bx-popup-chain .bx-popup-chain-item {
+        -webkit-box-shadow: @bx-shadow-popup;
+        -moz-box-shadow: @bx-shadow-popup;
+        box-shadow: @bx-shadow-popup;
+    }
+    .bx-popup-applied.bx-popup-chain .bx-popup-chain-item a:hover {
+        background-color: @bx-color-hl;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper {
+        -webkit-box-shadow: @bx-shadow-menu-slide;
+        -moz-box-shadow: @bx-shadow-menu-slide;
+        box-shadow: @bx-shadow-menu-slide;
+    }
+    .bx-btn {
+        -webkit-box-shadow: @bx-shadow-button;
+        -moz-box-shadow: @bx-shadow-button;
+        box-shadow: @bx-shadow-button;
+    }
+    .bx-btn.bx-btn-small {
+        -webkit-box-shadow: @bx-shadow-button-small;
+        -moz-box-shadow: @bx-shadow-button-small;
+        box-shadow: @bx-shadow-button-small;
+    }
+
+
+    /* background images */
+    .bx-def-image-bg-header,
+    .bx-def-image-bg-footer,
+    .bx-def-image-bg-block,
+    .bx-def-box,
+    .bx-popup-color-bg,
+    .bx-popup-wrapper.bx-popup-slide-wrapper,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main,
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main,
+    #bx-sliding-menu-account.bx-sliding-menu-main,
+    .bx-menu-main-bar-wrapper {
+        background-position: center center;
+    }
+    .bx-def-image-bg-header {
+        background-image: @bx-image-bg-header;
+        background-repeat: @bx-image-bg-header-repeat;
+        background-attachment: @bx-image-bg-header-attachment;
+        background-size: @bx-image-bg-header-size;
+    }
+    .bx-def-image-bg-footer {
+        background-image: @bx-image-bg-footer;
+        background-repeat: @bx-image-bg-footer-repeat;
+        background-attachment: @bx-image-bg-footer-attachment;
+        background-size: @bx-image-bg-footer-size;
+    }
+    
+    .bx-def-image-bg-block {
+        background-image: @bx-image-bg-block;
+        background-repeat: @bx-image-bg-block-repeat;
+        background-attachment: @bx-image-bg-block-attachment;
+        background-size: @bx-image-bg-block-size;
+    }
+    .bx-def-box {
+        background-image: @bx-image-bg-box;
+        background-repeat: @bx-image-bg-box-repeat;
+        background-attachment: @bx-image-bg-box-attachment;
+        background-size: @bx-image-bg-box-size;
+    }
+
+    /* body */
+    a {
+        color: @bx-color-link-body; 
+        transition: color .3s;
+    }
+    a:hover {
+        color: @bx-color-link-body-hover; 
+    }
+    .sys-icon:not(.sys-colored):not(.bx-vote-star),
+    .sys-icon-a:not(.sys-colored):not(.bx-vote-star) {
+        color: inherit; 
+    }
+    a:hover > .sys-icon:not(.sys-colored),
+    a:hover > .sys-icon-a:not(.sys-colored) {
+        color: @bx-color-icon-body-hover; 
+    }
+    .sys-icon-a i {
+        .background-color (@bx-color-icon-body) !important;
+        color: @bx-color-icon-body;
+    }
+    a:hover > .sys-icon-a i {
+        .background-color (@bx-color-icon-body-hover) !important;
+        color: @bx-color-icon-body-hover;
+    }
+
+    /* header */
+    .bx-header.bx-def-color-bg-header {
+        .background-color (@bx-color-header);
+    }
+    .bx-header.bx-def-border-header {
+        border-bottom-width: @bx-border-width-header;
+        border-bottom-style: @bx-border-type;
+        border-bottom-color: @bx-color-border-header;
+    }
+    .bx-header a {
+        color: @bx-color-link-header; 
+    }
+    .bx-header a:hover {
+        color: @bx-color-link-header-hover;
+    }
+    .bx-header .sys-icon:not(.sys-colored),
+    .bx-header .sys-icon-a:not(.sys-colored) {
+        color: @bx-color-icon-header; 
+    }
+    .bx-header .cd-nav-trigger span, 
+    .bx-header .cd-nav-trigger span::before, 
+    .bx-header .cd-nav-trigger span::after,
+    .bx-header .cd-nav-trigger.nav-is-visible span::before, 
+    .bx-header .cd-nav-trigger.nav-is-visible span::after {
+        background: @bx-color-icon-header;
+    }
+    .bx-header a:hover .sys-icon,
+    .bx-header a:hover .sys-icon-a {
+        color: @bx-color-icon-header-hover; 
+    }
+    .bx-header .cd-nav-trigger.nav-is-visible:hover span {
+      background: rgba(255, 255, 255, 0);
+    }
+    .bx-header .cd-nav-trigger:hover span, 
+    .bx-header .cd-nav-trigger:hover span::before, 
+    .bx-header .cd-nav-trigger:hover span::after,
+    .bx-header .cd-nav-trigger.nav-is-visible:hover span::before, 
+    .bx-header .cd-nav-trigger.nav-is-visible:hover span::after {
+        background: @bx-color-icon-header-hover;
+    }
+    .bx-header .sys-icon-a:not(.sys-colored) i {
+        .background-color (@bx-color-icon-header) !important;
+        color: @bx-color-icon-header;
+    }
+    .bx-header a:hover .sys-icon-a i {
+        .background-color (@bx-color-icon-header-hover) !important;
+        color: @bx-color-icon-header-hover;
+    }
+
+    /* footer */
+    .bx-footer-wrapper.bx-def-color-bg-footer {
+        .background-color (@bx-color-footer);    
+    }
+    .bx-footer-wrapper.bx-def-border-footer {
+        border-top-width: @bx-border-width-footer;
+        border-top-style: @bx-border-type;
+        border-top-color: @bx-color-border-footer;
+    }
+
+    .bx-footer {
+        color: @bx-font-color-footer;
+    }
+    .bx-footer a {
+        color: @bx-color-link-footer; 
+    }
+    .bx-footer a:hover {
+        color: @bx-color-link-footer-hover; 
+    }
+    .bx-footer .sys-icon,
+    .bx-footer .sys-icon-a {
+        color: @bx-color-icon-footer; 
+    }
+    .bx-footer a:hover .sys-icon,
+    .bx-footer a:hover .sys-icon-a {
+        color: @bx-color-icon-footer-hover; 
+    }
+    .bx-footer .sys-icon-a i {
+        .background-color (@bx-color-icon-footer) !important;
+        color: @bx-color-icon-footer;
+    }
+    .bx-footer a:hover .sys-icon-a i {
+        .background-color (@bx-color-icon-footer-hover) !important;
+        color: @bx-color-icon-footer-hover;
+    }
+
+    /* fonts */
+    .bx-def-font-inputs {
+        font-family: @bx-font-family-form-input;
+        font-size: @bx-font-size-form-input;
+        color: @bx-font-color-form-input;
+    }
+
+    h1,
+    .bx-def-font-h1 {
+        font-weight: @bx-font-weight-h1;
+        color: @bx-font-color-default-h1;
+    }
+    h1.bx-def-font-grayed,
+    h1 .bx-def-font-grayed,
+    .bx-def-font-h1.bx-def-font-grayed,
+    .bx-def-font-h1 .bx-def-font-grayed {
+        color: @bx-font-color-grayed-h1;
+    }
+    h1.bx-def-font-contrasted,
+    h1.bx-def-font-contrasted:after,
+    h1.bx-def-font-contrasted:before,
+    h1 .bx-def-font-contrasted,
+    h1 .bx-def-font-contrasted:after,
+    h1 .bx-def-font-contrasted:before,
+    .bx-def-font-h1.bx-def-font-contrasted,
+    .bx-def-font-h1.bx-def-font-contrasted:after,
+    .bx-def-font-h1.bx-def-font-contrasted:before,
+    .bx-def-font-h1 .bx-def-font-contrasted,
+    .bx-def-font-h1 .bx-def-font-contrasted:after,
+    .bx-def-font-h1 .bx-def-font-contrasted:before {
+        color: @bx-font-color-contrasted-h1;
+    }
+    h1 a,
+    .bx-def-font-h1 a,
+    a.bx-def-font-h1 {
+        color: @bx-font-color-link-h1;
+    }
+    h1 a:hover,
+    .bx-def-font-h1 a:hover,
+    a.bx-def-font-h1:hover {
+        color: @bx-font-color-link-h1-hover;
+    }
+
+    h2,
+    .bx-def-font-h2 {
+        font-weight: @bx-font-weight-h2;
+        color: @bx-font-color-default-h2;
+    }
+    h2.bx-def-font-grayed,
+    h2 .bx-def-font-grayed,
+    .bx-def-font-h2.bx-def-font-grayed,
+    .bx-def-font-h2 .bx-def-font-grayed {
+        color: @bx-font-color-grayed-h2;
+    }
+    h2.bx-def-font-contrasted,
+    h2.bx-def-font-contrasted:after,
+    h2.bx-def-font-contrasted:before,
+    h2 .bx-def-font-contrasted,
+    h2 .bx-def-font-contrasted:after,
+    h2 .bx-def-font-contrasted:before,
+    .bx-def-font-h2.bx-def-font-contrasted,
+    .bx-def-font-h2.bx-def-font-contrasted:after,
+    .bx-def-font-h2.bx-def-font-contrasted:before,
+    .bx-def-font-h2 .bx-def-font-contrasted,
+    .bx-def-font-h2 .bx-def-font-contrasted:after,
+    .bx-def-font-h2 .bx-def-font-contrasted:before {
+        color: @bx-font-color-contrasted-h2;
+    }
+    h2 a,
+    .bx-def-font-h2 a,
+    a.bx-def-font-h2 {
+        color: @bx-font-color-link-h2;
+    }
+    h2 a:hover,
+    .bx-def-font-h2 a:hover,
+    a.bx-def-font-h2:hover {
+        color: @bx-font-color-link-h2-hover;
+    }
+
+    h3,
+    .bx-def-font-h3 {
+        font-weight: @bx-font-weight-h3;
+        color: @bx-font-color-default-h3;
+    }
+    h3.bx-def-font-grayed,
+    h3 .bx-def-font-grayed,
+    .bx-def-font-h3.bx-def-font-grayed,
+    .bx-def-font-h3 .bx-def-font-grayed {
+        color: @bx-font-color-grayed-h3;
+    }
+    h3.bx-def-font-contrasted,
+    h3.bx-def-font-contrasted:after,
+    h3.bx-def-font-contrasted:before,
+    h3 .bx-def-font-contrasted,
+    h3 .bx-def-font-contrasted:after,
+    h3 .bx-def-font-contrasted:before,
+    .bx-def-font-h3.bx-def-font-contrasted,
+    .bx-def-font-h3.bx-def-font-contrasted:after,
+    .bx-def-font-h3.bx-def-font-contrasted:before,
+    .bx-def-font-h3 .bx-def-font-contrasted,
+    .bx-def-font-h3 .bx-def-font-contrasted:after,
+    .bx-def-font-h3 .bx-def-font-contrasted:before {
+        color: @bx-font-color-contrasted-h3;
+    }
+    h3 a,
+    .bx-def-font-h3 a,
+    a.bx-def-font-h3 {
+        color: @bx-font-color-link-h3;
+    }
+    h3 a:hover,
+    .bx-def-font-h3 a:hover,
+    a.bx-def-font-h3:hover {
+        color: @bx-font-color-link-h3-hover;
+    }
+
+    /* cover */
+    .bx-menu-toolbar-padding .bx-def-cover-color-bg {
+        background-color: @bx-color-cover;
+    }
+
+    .bx-menu-toolbar-padding .bx-cover-wrapper {
+        border-width: @bx-border-width-cover;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-cover;
+
+        border-radius: @bx-border-radius-cover;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-cover;
+        -moz-box-shadow: @bx-shadow-cover;
+        box-shadow: @bx-shadow-cover;
+    }
+    .bx-cover-wrapper .bx-cover {
+        min-height: @bx-height-cover;
+    }
+    .bx-cover-wrapper .bx-cover,
+    .bx-cover-wrapper .bx-cover .bx-cover-actions .bx-menu-btns-hor {
+        text-align: @bx-text-align-cover;
+    }
+    .bx-cover-wrapper .bx-cover.bx-def-padding {
+        padding: @bx-content-padding-cover;
+    }
+    .bx-cover-wrapper .bx-cover .bx-cover-image img {
+        border-width: @bx-border-width-cover-icon;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-cover-icon;
+
+        border-radius: @bx-border-radius-cover-icon;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-cover-icon;
+        -moz-box-shadow: @bx-shadow-cover-icon;
+        box-shadow: @bx-shadow-cover-icon;
+    }
+
+    .bx-cover-wrapper .bx-cover .bx-cover-title {
+        text-shadow: @bx-shadow-text-cover;
+
+        font-family: @bx-font-family-cover;
+    }
+    .bx-cover-wrapper .bx-cover .bx-cover-title,
+    .bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted,
+    .bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted:after,
+    .bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted:before {
+        color: @bx-color-font-cover;
+    }
+    .bx-cover-wrapper .bx-cover .bx-cover-title,
+    .bx-cover-wrapper .bx-cover .bx-cover-title.bx-def-font-h1 {
+        font-size: @bx-font-size-cover;
+        font-weight: @bx-font-weight-cover;
+    }
+
+
+    /* block */
+    .bx-def-border-block {
+        border-width: @bx-border-width-block;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-block;
+
+        border-radius: @bx-border-radius-block;
+        background-clip: padding-box;
+    }
+    .bx-def-border-radius-block {
+        border-radius: @bx-border-radius-block;
+        background-clip: padding-box;
+    }
+    .bx-db-header {
+        padding: @bx-title-padding-block;
+
+        border-width: @bx-border-width-block-title;
+        border-style: solid;
+        border-color: @bx-color-border-block-title;
+
+        border-radius: @bx-border-radius-block-title;
+    }
+    .bx-def-color-bg-block .bx-db-header,
+    .bx-def-image-bg-block .bx-db-header {
+        background-color: @bx-color-block-title;
+    }
+    .bx-db-header .bx-db-title {
+        line-height: 1.2;
+        font-family: @bx-font-family-block-title;
+        font-size: @bx-font-size-block-title;
+        font-weight: @bx-font-weight-block-title;
+        color: @bx-color-font-block-title;
+    }
+    .bx-db-divider {
+        border-top:@bx-height-block-title-div @bx-border-type @bx-color-block-title-div;
+    }
+
+
+    /* box */
+    .bx-def-box {
+        border-width: @bx-border-width-box;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-box;
+    }
+    .bx-def-box.bx-def-padding {
+        padding: @bx-content-padding-card;
+    }
+    .bx-def-box.bx-def-color-bg-box {
+        .background-color (@bx-color-box);
+    }
+    .bx-def-box.bx-def-color-bg-box-active,
+    .bx-def-box.bx-def-color-bg-box-hover:hover {
+        .background-color (@bx-color-box-hover);
+    }
+    .bx-def-box-round-corners,
+    .bx-def-box.bx-def-round-corners {
+        border-radius: @bx-border-radius-box;
+        background-clip: padding-box;
+    }
+    .bx-def-box-round-corners-int {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+        background-clip: padding-box;
+    }
+    .bx-def-box-round-corners-int-top {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+        background-clip: padding-box;
+    }
+    .bx-def-box-round-corners-int-bottom {
+        border-radius: 0 0 @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+        background-clip: padding-box;
+    }
+    .bx-base-pofile-unit-with-cover .bx-def-round-corners .bx-base-pofile-unit-cover {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    }
+    .bx-base-text-unit.bx-base-text-unit-ext.bx-def-round-corners img.bx-base-text-unit-cover.bx-def-round-corners,
+    .bx-base-text-unit.bx-base-text-unit-ext .bx-def-round-corners img.bx-base-text-unit-cover.bx-def-round-corners {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    }
+    .bx-base-text-unit.bx-base-text-unit-gallery.bx-def-round-corners .bx-base-text-unit-thumb.bx-def-round-corners,
+    .bx-base-text-unit.bx-base-text-unit-gallery .bx-def-round-corners .bx-base-text-unit-thumb.bx-def-round-corners {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    }
+
+    /* popup */
+    .bx-popup-border {
+        border-width: @bx-border-width-popup;
+        border-style: solid;
+        border-color: @bx-color-border-popup;
+
+        border-radius: @bx-border-radius-popup;
+        background-clip: padding-box;
+    }
+    .bx-popup-color-bg {
+        background-color: @bx-color-popup;
+
+        background-image: @bx-image-bg-popup;
+        background-repeat: @bx-image-bg-popup-repeat;
+        background-attachment: @bx-image-bg-popup-attachment;
+        background-size: @bx-image-bg-popup-size;
+    }
+    .bx-popup-content-indent {
+        padding: @bx-content-padding-popup;
+    }
+    .bx-popup-header {
+        padding: @bx-title-padding-popup;
+    }
+    .bx-popup-header .bx-popup-element-close {
+        margin: @bx-title-padding-popup;
+    }
+    .bx-popup-header-color-bg {
+        background-color: @bx-color-popup-title;
+    }
+    .bx-popup-header h2,
+    .bx-popup-header .bx-popup-element-close {
+        line-height: 1.8rem;
+    }
+    .bx-popup-header h2 {
+        font-family: @bx-font-family-popup-title;
+        font-size: @bx-font-size-popup-title;
+    }
+    .bx-popup-header h2,
+    .bx-popup-header.bx-def-font-contrasted h2,
+    .bx-popup-header .bx-popup-element-close,
+    .bx-popup-header.bx-def-font-contrasted .bx-popup-element-close,
+    .bx-popup-header .bx-popup-element-close .sys-icon,
+    .bx-popup-header.bx-def-font-contrasted .bx-popup-element-close .sys-icon {
+        color: @bx-color-font-popup-title;
+    }
+
+    /* slide menu */
+    .bx-popup-wrapper.bx-popup-slide-wrapper {
+        border-width: @bx-border-width-menu-slide;
+        border-style: solid;
+        border-color: @bx-color-border-menu-slide;
+
+        .background-color (@bx-color-menu-slide);
+
+        background-image: @bx-image-bg-menu-slide;
+        background-repeat: @bx-image-bg-menu-slide-repeat;
+        background-attachment: @bx-image-bg-menu-slide-attachment;
+        background-size: @bx-image-bg-menu-slide-size;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper.bx-def-padding {
+        padding: @bx-content-padding-menu-slide;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper li a {
+        text-shadow: @bx-shadow-font-menu-slide;
+
+        font-family: @bx-font-family-menu-slide;
+        font-size: @bx-font-size-menu-slide;
+        font-weight: @bx-font-weight-menu-slide;
+        color: @bx-font-color-menu-slide;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper li a:hover {
+        color: @bx-font-color-menu-slide-hover;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper li.bx-menu-tab-active a,
+    .bx-popup-wrapper.bx-popup-slide-wrapper li.bx-menu-inter-act {
+        color: @bx-font-color-menu-slide-active;
+    }
+
+    /* main menu */
+    .cd-main-content .cd-side-nav {
+        -webkit-box-shadow: @bx-shadow-menu-main;
+        -moz-box-shadow: @bx-shadow-menu-main;
+        box-shadow: @bx-shadow-menu-main;
+
+        border-width: @bx-border-width-menu-main;
+        border-style: solid;
+        border-color: @bx-color-border-menu-main;
+
+        background-color: @bx-color-menu-main;
+
+        background-image: @bx-image-bg-menu-main;
+        background-repeat: @bx-image-bg-menu-main-repeat;
+        background-attachment: @bx-image-bg-menu-main-attachment;
+        background-size: @bx-image-bg-menu-main-size;
+    }
+
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt {
+        padding: @bx-content-padding-menu-main;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a .bx-menu-floating-blocks-title {
+        text-shadow: @bx-shadow-font-menu-main;
+
+        font-family: @bx-font-family-menu-main;
+        font-size: @bx-font-size-menu-main;
+        font-weight: @bx-font-weight-menu-main;
+        color: @bx-font-color-menu-main;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .bx-menu-floating-blocks-title,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .bx-menu-floating-blocks-icon {
+        color: @bx-font-color-menu-main-active;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover .bx-menu-floating-blocks-title,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover .bx-menu-floating-blocks-icon {
+        color: @bx-font-color-menu-main-hover;
+    }
+
+
+    /* account menu */
+    #bx-sliding-menu-account.bx-sliding-menu-main {
+        -webkit-box-shadow: @bx-shadow-menu-account;
+        -moz-box-shadow: @bx-shadow-menu-account;
+        box-shadow: @bx-shadow-menu-account;
+
+        border-width: @bx-border-width-menu-account;
+        border-style: solid;
+        border-color: @bx-color-border-menu-account;
+
+        background-color: @bx-color-menu-account;
+
+        background-image: @bx-image-bg-menu-account;
+        background-repeat: @bx-image-bg-menu-account-repeat;
+        background-attachment: @bx-image-bg-menu-account-attachment;
+        background-size: @bx-image-bg-menu-account-size;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt {
+        padding: @bx-content-padding-menu-account;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .bx-def-font-h1,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .bx-def-font-h2,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt a:not(.bx-btn) {
+        color: @bx-font-color-menu-account;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a .bx-menu-floating-blocks-title {
+        text-shadow: @bx-shadow-font-menu-account;
+
+        font-family: @bx-font-family-menu-account;
+        font-size: @bx-font-size-menu-account;
+        font-weight: @bx-font-weight-menu-account;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li.bx-menu-tab-active a {
+        color: @bx-font-color-menu-account-active;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a:hover {
+        color: @bx-font-color-menu-account-hover;
+    }
+
+    /* add menu */
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main {
+        -webkit-box-shadow: @bx-shadow-menu-add;
+        -moz-box-shadow: @bx-shadow-menu-add;
+        box-shadow: @bx-shadow-menu-add;
+
+        border-width: @bx-border-width-menu-add;
+        border-style: solid;
+        border-color: @bx-color-border-menu-add;
+
+        background-color: @bx-color-menu-add;
+
+        background-image: @bx-image-bg-menu-add;
+        background-repeat: @bx-image-bg-menu-add-repeat;
+        background-attachment: @bx-image-bg-menu-add-attachment;
+        background-size: @bx-image-bg-menu-add-size;
+    }
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt {
+        padding: @bx-content-padding-menu-add;
+    }
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a {
+        text-shadow: @bx-shadow-font-menu-add;
+
+        font-family: @bx-font-family-menu-add;
+        font-size: @bx-font-size-menu-add;
+        font-weight: @bx-font-weight-menu-add;
+        color: @bx-font-color-menu-add;
+    }
+    /*#bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a {
+        color: @bx-font-color-menu-add-active;
+    }*/
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a:hover {
+        color: @bx-font-color-menu-add-hover;
+    }
+
+    /* page menu */
+    .bx-menu-main-bar-wrapper {
+        -webkit-box-shadow: @bx-shadow-menu-page;
+        -moz-box-shadow: @bx-shadow-menu-page;
+        box-shadow: @bx-shadow-menu-page;
+
+        border-width: @bx-border-width-menu-page;
+        border-style: solid;
+        border-color: @bx-color-border-menu-page;
+        border-bottom-right-radius: @bx-border-radius-block-br;
+        border-bottom-left-radius: @bx-border-radius-block-bl;
+
+        background-color: @bx-color-menu-page;
+
+        background-image: @bx-image-bg-menu-page;
+        background-repeat: @bx-image-bg-menu-page-repeat;
+        background-attachment: @bx-image-bg-menu-page-attachment;
+        background-size: @bx-image-bg-menu-page-size;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu {
+        padding: @bx-content-padding-menu-page;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu li a {
+        text-shadow: @bx-shadow-font-menu-page;
+
+        font-family: @bx-font-family-menu-page;
+        font-size: @bx-font-size-menu-page;
+        font-weight: @bx-font-weight-menu-page;
+        color: @bx-font-color-menu-page;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu li a:hover {
+        color: @bx-font-color-menu-page-hover;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu li.bx-menu-tab-active a {
+        color: @bx-font-color-menu-page-active;
+    }
+
+    /* form */
+    .bx-form-value .bx-form-input-slider,
+    .bx-form-value .bx-form-input-doublerange,
+    .bx-form-value .bx-form-input-select_multiple,
+    .bx-form-value .bx-form-input-select,
+    .bx-form-value .bx-form-input-radio_set,
+    .bx-form-value .bx-form-input-checkbox_set,
+    .bx-form-value .bx-form-input-number,
+    .bx-form-value .bx-form-input-time,
+    .bx-form-value .bx-form-input-datepicker,
+    .bx-form-value .bx-form-input-datetime,
+    .bx-form-value .bx-form-input-textarea,
+    .bx-form-value .bx-form-input-text,
+    .bx-form-value .bx-form-input-price,
+    .bx-form-value .bx-form-input-wrapper-price span,
+    .bx-form-value .bx-form-input-wrapper-password {
+        .box-sizing(@base-input-box-sizing);
+
+        border-color: @bx-color-border-form-input;
+        border-width: @bx-border-width-form-input;
+
+        background-color: @bx-color-form-input;
+
+        -webkit-box-shadow: @bx-shadow-form-input;
+        -moz-box-shadow: @bx-shadow-form-input;
+        box-shadow: @bx-shadow-form-input;
+    }
+    .bx-form-value .bx-form-input-slider,
+    .bx-form-value .bx-form-input-doublerange,
+    .bx-form-value .bx-form-input-select,
+    .bx-form-value .bx-form-input-number,
+    .bx-form-value .bx-form-input-time,
+    .bx-form-value .bx-form-input-datepicker,
+    .bx-form-value .bx-form-input-datetime,
+    .bx-form-value .bx-form-input-text,
+    .bx-form-value .bx-form-input-price,
+    .bx-form-value .bx-form-input-wrapper-price span,
+    .bx-form-value .bx-form-input-wrapper-password {
+        height: @bx-height-form-input + 0.25rem;
+    }
+    .bx-form-value .bx-form-input-text.bx-form-input-autotoken:not(.bx-form-input-labels) b {
+        line-height: @bx-height-form-input;
+    }
+    .bx-form-value .bx-form-input-text.bx-form-input-autotoken:not(.bx-form-input-labels) b .bx-def-thumb-size {
+        width: @bx-height-form-input;
+        height: @bx-height-form-input;
+        line-height: @bx-height-form-input;
+    }
+    .bx-form-value .bx-form-input-slider:focus,
+    .bx-form-value .bx-form-input-doublerange:focus,
+    .bx-form-value .bx-form-input-number:focus,
+    .bx-form-value .bx-form-input-time:focus,
+    .bx-form-value .bx-form-input-datepicker:focus,
+    .bx-form-value .bx-form-input-datetime:focus,
+    .bx-form-value .bx-form-input-textarea:focus,
+    .bx-form-value .bx-form-input-text:focus,
+    .bx-form-value .bx-form-input-price:focus,
+    .bx-form-value .bx-form-input-wrapper-password.bx-form-input-focus {
+        border-color: @bx-color-border-form-input-active;
+        background-color: @bx-color-form-input-active;
+    }
+    .bx-form-value .bx-switcher-cont.on > button {
+        background-color: @bx-color-form-input;
+    }
+
+    /* button large */
+    .bx-btn,
+    .bx-btn.bx-btn-primary {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button;
+        line-height: (@bx-height-button - 0.125 * @bx-border-width-button);
+
+        .background-color (@bx-color-button);
+
+        border-width: @bx-border-width-button;
+        border-style: solid;
+        border-color: @bx-color-border-button;
+
+            border-radius: @bx-border-radius-button;
+        background-clip: padding-box;
+
+        text-shadow: @bx-shadow-font-button;
+
+        font-family: @bx-font-family-button;
+        font-size: @bx-font-size-button;
+        font-weight: @bx-font-weight-button;
+        color: @bx-font-color-button;
+        
+        padding-top: 0px;
+        padding-bottom: 0px;
+    }
+    .bx-btn-height {
+        height: @bx-height-button;
+        line-height: @bx-height-button;
+    }
+    .bx-btn-border {
+        border-width: @bx-border-width-button;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn:hover,
+    .bx-btn:active,
+    .bx-btn.bx-btn-primary:hover,
+    .bx-btn.bx-btn-primary:active {
+        border-width: @bx-border-width-button;
+        border-style: solid;
+        border-color: @bx-color-border-button-hover;
+
+        .background-color (@bx-color-button-hover);
+
+        color: @bx-font-color-button-hover;
+    }
+    .bx-btn .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button;
+    }
+    .bx-btn:hover .sys-icon:not(.sys-colored),
+    .bx-btn:active .sys-icon:not(.sys-colored),
+    .bx-btn.bx-btn-primary:hover .sys-icon:not(.sys-colored),
+    .bx-btn.bx-btn-primary:active .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button-hover;
+    }
+
+    /* button small */
+    .bx-btn.bx-btn-small {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button-small;
+        line-height: (@bx-height-button-small - 0.125 * @bx-border-width-button-small);
+
+        .background-color (@bx-color-button-small);
+
+        border-width: @bx-border-width-button-small;
+        border-style: solid;
+        border-color: @bx-color-border-button-small;
+
+            border-radius: @bx-border-radius-button-small;
+        background-clip: padding-box;
+
+        text-shadow: @bx-shadow-font-button-small;
+
+        font-family: @bx-font-family-button-small;
+        font-size: @bx-font-size-button-small;
+        font-weight: @bx-font-weight-button-small;
+        color: @bx-font-color-button-small;
+    }
+    .bx-btn-small-height {
+        height: @bx-height-button-small;
+        line-height: @bx-height-button-small;
+    }
+    .bx-btn-small-border {
+        border-width: @bx-border-width-button-small;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn.bx-btn-small:hover,
+    .bx-btn.bx-btn-small:active {
+        border-width: @bx-border-width-button-small;
+        border-style: solid;
+        border-color: @bx-color-border-button-small-hover;
+
+        .background-color (@bx-color-button-small-hover);
+
+        color: @bx-font-color-button-small-hover;
+    }
+    .bx-btn.bx-btn-small .sys-icon {
+        color: @bx-font-color-button-small;
+    }
+    .bx-btn.bx-btn-small:hover .sys-icon,
+    .bx-btn.bx-btn-small:active .sys-icon {
+        color: @bx-font-color-button-small-hover;
+    }
+}
+
+/* viewport */
+html.bx-media-tablet {
+    font-size: @bx-viewport-font-tablet;
+}
+
+html.bx-media-phone {
+    font-size: @bx-viewport-font-mobile;
+}

+ 344 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/css/menu.less

@@ -0,0 +1,344 @@
+@import (reference) 'default.less';
+@import '../../../../../../../template/css/menu.css';
+
+.@{bx-root-class-name} {
+
+    .bx-menu-toolbar-padding {
+        padding-top: 0;
+    }
+
+    /*--- Main (Side) Menu ---*/
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site {
+        display: block;
+        white-space: normal;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site .bx-def-color-bg-hl-hover:hover
+    {
+        background-color: inherit;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li {
+        display: block;
+        width: auto;
+        height: auto;
+        position: relative;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li a{
+        padding: 0.5rem 1rem;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .bx-menu-floating-blocks-icon, 
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .bx-menu-floating-blocks-title {
+        display: inline-block;
+        vertical-align: top;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .bx-menu-floating-blocks-title {
+        line-height: 2rem;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li img,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .sys-icon {
+        width: 2rem;
+        height: 2rem;
+
+        margin: 0px;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .sys-icon {
+        line-height: 2rem;
+        font-size: 1.2rem;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li img {
+        background-pocition: center center;
+        background-repeat: none;
+        background-size: 60% 60%;
+    }
+
+
+    /*--- Account Popup ---*/	
+    #bx-sliding-menu-account.bx-sliding-menu-main.bx-sliding-menu-fullheight {
+        height: calc(100% - 4rem);
+    }
+
+
+    /*--- Account Popup Submenu & Add Content Menu ---*/
+    .bx-menu-account-popup-profile,
+    .bx-menu-account-popup-menu {
+        text-align: left;
+    }
+    .bx-menu-account-popup-menu ul.bx-menu-floating-blocks-wide,
+    .bx-menu-object-sys_account_notifications li,
+    .bx-menu-object-sys_add_content li {
+        display: block;
+        width: 100%;
+        height: auto;
+    }
+    .bx-menu-object-sys_account_notifications li A,
+    .bx-menu-object-sys_add_content li A {
+        padding: 0.25rem 0.5rem;
+        line-height: 2rem;
+        height: 2rem;
+    }
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-icon,
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-title,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-icon,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-title {
+        display: inline-block;
+        vertical-align: middle;
+    }
+    .bx-menu-object-sys_account_notifications li a,
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-title,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-title {
+        line-height: 1.875rem;
+    }
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-title,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-title {
+        padding-right: 0.5rem;
+    }
+    .bx-menu-object-sys_account_notifications li img,
+    .bx-menu-object-sys_account_notifications li .sys-icon,
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-icon img,
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-icon .sys-icon,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-icon img,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-icon .sys-icon {
+        height: 2rem;
+        width: 2rem;
+
+        margin: 0px;	
+    }
+    .bx-menu-object-sys_account_notifications li .sys-icon,
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-icon .sys-icon,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-icon .sys-icon {
+        line-height: 2rem;
+        font-size: 1.2rem;
+    }
+    .bx-menu-object-sys_account_notifications li img,
+    .bx-menu-object-sys_account_notifications li .bx-menu-floating-blocks-icon img,
+    .bx-menu-object-sys_add_content li .bx-menu-floating-blocks-icon img {
+        background-pocition: center center;
+        background-repeat: none;
+        background-size: 60% 60%;
+    }
+    .bx-menu-object-sys_account_notifications li .bx-def-unit-alert-middle {
+        top: 4px;
+        right: 4px;
+    }
+    .bx-menu-object-sys_account_notifications li:hover {
+        opacity:0.8;
+    }
+
+
+    /*--- Add Content Menu ---*/
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-menu-object-sys_add_content {
+        display: block;
+        width: 100%;
+    }
+
+
+    /*--- Popup menus (vertical) ---*/
+    .bx-popup .bx-popup-content-indent ul.bx-menu-ver,
+    .bx-popup .bx-popup-content-indent ul.bx-menu-custom.bx-menu-custom-ver {
+        margin: -0.5rem;
+    }
+    .bx-popup ul.bx-menu-ver li,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li {
+        margin-top: 0;
+        margin-bottom: 0;
+    }
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver.bx-menu-submenu-more-auto li.bx-menu-item,
+    .bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto .bx-popup .bx-menu-item {
+        padding: 0;
+        line-height: normal;
+    }
+    .bx-popup ul.bx-menu-ver li div.bx-def-padding-sec,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li > span,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li > .bx-def-margin-thd-topbottom,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li > .sys-action {
+        margin: 0;
+        padding: 0.25rem 0.5rem;
+    }
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver.bx-menu-submenu-more-auto li > span,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver.bx-menu-submenu-more-auto li > .bx-def-margin-thd-topbottom {
+        margin: 0;
+        padding-right: 0.5rem;
+    }
+    .bx-popup ul.bx-menu-ver li > a,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li > span > a,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li > span > span,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li > span > span > a,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li .bx-menu-item-link,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li .bx-report-element-holder,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li .bx-report-do-report {
+        margin: 0;
+        padding: 0;
+    }
+    .bx-popup ul.bx-menu-ver li a > div > span,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li a > span:not(.sys-action-do-icon) {
+        line-height: 1.5rem;
+        .font-size(@bx-font-size-middle);
+    }
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver.bx-menu-submenu-more-auto li.bx-menu-item a {
+        display: block;
+        line-height: 1.5rem;
+    }
+    .bx-popup ul.bx-menu-ver li a > div img,
+    .bx-popup ul.bx-menu-ver li a > div .sys-icon,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li a > img,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li a > .sys-icon,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li a > span.sys-action-do-icon,
+    .bx-popup ul.bx-menu-custom.bx-menu-custom-ver li a > span.sys-action-do-icon .sys-icon {
+        width: 1.0rem;
+        height: 1.0rem;
+        line-height: 1.0rem;
+        font-size: 1.0rem;
+    }
+
+
+    /*--- Custom Menu with More Auto ---*/
+    .bx-menu-main-submenu.bx-menu-more-auto .bx-menu-submenu-more-auto .bx-menu-item .bx-btn,
+    .bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto .bx-menu-submenu-more-auto .bx-menu-item a,
+    .bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto .bx-menu-submenu-more-auto .bx-menu-item .bx-btn {
+        font-weight: normal;
+        color: @bx-color-link-body;
+    }
+
+
+    .bx-menu-main-submenu.bx-menu-more-auto .bx-menu-submenu-more-auto .bx-menu-item .bx-btn .sys-icon,
+    .bx-menu-custom.bx-menu-custom-hor.bx-menu-more-auto .bx-menu-submenu-more-auto .bx-menu-item .bx-btn .sys-icon {
+        color: @bx-color-icon-body;
+    }
+
+    .bx-menu-object-sys_add_content .bx-def-color-bg-active{
+        background-color: inherit !important;
+    }
+
+    #bx-homepage-menu-sys_homepage li{
+        height: 5.6rem;
+    }
+    /*--- Main menu with submenu ---*/
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site > li.submenu-closed ul.bx-menu-floating-blocks-submenu {
+        display: none;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-floating-blocks-submenu {
+        margin: 0;
+        padding: 0;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-floating-blocks-submenu > li {
+        display: block;
+        width: auto;
+        height: auto;
+        padding-left: 2rem
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site > li.submenu-closed .bx-menu-fbt-closed {
+        display: block;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site > li.submenu-closed .bx-menu-fbt-opened {
+        display: none;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site > li > a > .bx-menu-floating-blocks-toggler {
+        float: right; 
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site .bx-menu-fbt-closed {
+        display: none;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site > li > a > .bx-menu-floating-blocks-toggler .sys-icon{
+        font-size: 0.5rem !important;
+        font-weight: bold !important;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site .bx-menu-tab-active{
+        background-color: #e6f7ff;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site .bx-menu-tab-active:after{
+        position: absolute;
+        top: 0;
+        right: 0;
+        bottom: 0;
+        border-right: 3px solid #1890ff;
+        content: '';
+        height: 100%;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site li:hover{
+        opacity: 1; 
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site A div{
+        transition: color .3s;
+    }
+    
+    .bx-menu-ver.bx-menu-vertical-more-less li a{
+        line-height: 2rem;
+    }
+    .bx-menu-ver.bx-menu-vertical-more-less li{
+        border-radius: 0.1875rem;
+    }
+    .bx-tl-v-submenu-cnt ul li.bx-menu-inter-act {
+        color: #000;
+    }
+    .bx-sliding-menu, .bx-sliding-menu-main{
+        width: auto;
+    }
+}
+
+.bx-media-tablet .@{bx-root-class-name} {
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .bx-menu-floating-blocks-icon, 
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .bx-menu-floating-blocks-title {
+        display: block;
+        text-align: center;
+    }
+
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .bx-menu-floating-blocks-title {
+        padding-left: 0px;
+    }
+
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li .sys-icon {
+        width: 100%;
+        font-size: 1.5rem;
+    }
+
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-object-sys_site li img {
+        margin: 0px auto;
+        background-size: 70% 70%;
+    }
+
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site > li > a > .bx-menu-floating-blocks-toggler{
+        display:  none;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-floating-blocks-submenu{
+        position: absolute;
+        background: #fff;
+        width: 150px;
+        left: 120px;
+        top:0px;
+        border-radius: 4px;
+        box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
+        border-width: 1px;
+        border-style: solid;
+        border-color: rgba(0, 0, 0, 0.1);
+        z-index: 1000;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-menu-floating-blocks-submenu li {
+        padding-left: 0rem;
+    }
+}
+
+.bx-media-phone .@{bx-root-class-name} { 
+    .cd-main-content .cd-side-nav {
+        position:fixed;
+        width:100%;
+        height: calc(100%);
+
+        overflow-x:hidden;
+        overflow-y:auto;
+
+        -webkit-overflow-scrolling:touch;
+    }
+}
+
+:where(.bx-media-tablet, .bx-media-desktop) .@{bx-root-class-name}{ 
+    /*--- Account Popup ---*/
+    #bx-sliding-menu-account.bx-sliding-menu-main {
+        width: auto !important;
+        border-radius: 4px;
+    }
+
+    /*--- Add Content Menu ---*/
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main {
+        width: auto !important;
+        border-radius: 4px;
+    }	
+}

+ 5 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/designbox_10.html

@@ -0,0 +1,5 @@
+<!-- Design Box 10 [start]: Content only + padding -->
+<div class="bx-db-container bx-dbc-notitle bx-dbc-nobg">
+    <div class="bx-db-content bx-content-padding-block bx-clearfix">__designbox_content__</div>
+</div>
+<!-- Design Box 10 [ end ] -->

+ 5 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/designbox_13.html

@@ -0,0 +1,5 @@
+<!-- Design Box 13 [start]: Content + background + padding -->
+<div class="bx-db-container bx-dbc-notitle bx-def-image-bg-block bx-def-color-bg-block bx-def-border-block bx-shadow-block">
+    <div class="bx-db-content bx-content-padding-block bx-clearfix">__designbox_content__</div>
+</div>
+<!-- Design Box 13 [ end ] -->

+ 5 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/source/data/template/system/designbox_3.html

@@ -0,0 +1,5 @@
+<!-- Design Box 3 [start]: Content + background -->
+<div class="bx-db-container bx-dbc-notitle bx-dbc-nopadding bx-def-image-bg-block bx-def-color-bg-block bx-def-border-block bx-shadow-block">
+    <div class="bx-db-content bx-clearfix">__designbox_content__</div>
+</div>
+<!-- Design Box 3 [ end ] -->

+ 68 - 0
modules/boonex/decorous/updates/13.0.4_13.0.5/source/install/config.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Decorous Decorous template
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_TEMPLATE,
+    'name' => 'bx_decorous',
+    'title' => 'Decorous',
+    'note' => 'Design template',
+    'version' => '13.0.5',
+    'vendor' => 'Boonex',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/decorous/',
+    'home_uri' => 'decorous',
+
+    'db_prefix' => 'bx_decorous_',
+    'class_prefix' => 'BxDecorous',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Decorous Template',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'clear_db_cache' => 1
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'clear_db_cache' => 1
+    ),
+    'enable' => array(
+        'execute_sql' => 1
+    ),
+    'disable' => array(
+        'execute_sql' => 1
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 51 - 0
modules/boonex/events/updates/13.0.3_13.0.4/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Events',
+    'version_from' => '13.0.3',
+    'version_to' => '13.0.4',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/events/updates/update_13.0.3_13.0.4/',
+    'home_uri' => 'events_update_1303_1304',
+
+    'module_dir' => 'boonex/events/',
+    'module_uri' => 'events',
+
+    'db_prefix' => 'bx_events_',
+    'class_prefix' => 'BxEvents',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Events',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/events/updates/13.0.3_13.0.4/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxEventsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 301 - 0
modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsConfig.php

@@ -0,0 +1,301 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Events Events
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEventsConfig extends BxBaseModGroupsConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_aMenuItems2MethodsActions = array_merge($this->_aMenuItems2MethodsActions, array(
+            'view-event-profile' => 'checkAllowedView',
+            'edit-event-profile' => 'checkAllowedEdit',
+            'edit-event-cover' => 'checkAllowedChangeCover',
+            'invite-to-event' => 'checkAllowedInvite',
+            'delete-event-profile' => 'checkAllowedDelete',
+            'approve-event-profile' => 'checkAllowedApprove',
+            'ical-export' => 'checkAllowedIcalExport',
+        ));
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'calendar col-red2',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+            'TABLE_ENTRIES_FULLTEXT' => 'search_fields',
+            'TABLE_ADMINS' => $aModule['db_prefix'] . 'admins',
+            'TABLE_INVITES' => $aModule['db_prefix'] . 'invites',
+            'TABLE_PRICES' => $aModule['db_prefix'] . 'prices',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_PUBLISHED' => 'published',
+            'FIELD_NAME' => 'event_name',
+            'FIELD_TITLE' => 'event_name',
+            'FIELD_TEXT' => 'event_desc',
+            'FIELD_CATEGORY' => 'event_cat',
+            'FIELD_PICTURE' => 'picture',
+            'FIELD_COVER' => 'cover',
+            'FIELD_DATE_START' => 'date_start',
+            'FIELD_DATE_END' => 'date_end',
+            'FIELD_TIMEZONE' => 'timezone',
+            'FIELD_JOIN_CONFIRMATION' => 'join_confirmation',
+            'FIELD_REMINDER' => 'reminder',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+            'FIELD_ALLOW_POST_TO' => 'allow_post_to',
+            'FIELD_CF' => 'cf',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_VOTES' => 'votes',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELD_STATUS' => 'status',
+            'FIELD_STATUS_ADMIN' => 'status_admin',
+            'FIELDS_QUICK_SEARCH' => array('event_name'),
+            'FIELD_LOCATION' => 'location',
+            'FIELD_LOCATION_PREFIX' => 'location',
+            'FIELDS_WITH_KEYWORDS' => 'auto', // can be 'auto', array of fields or comma separated string of field names, works only when OBJECT_METATAGS is specified
+            'FIELD_LABELS' => 'labels',
+
+            'FIELD_PRICE_ROLE_ID' => 'role_id',
+            'FIELD_PRICE_NAME' => 'name',
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-event-profile',
+            'URI_EDIT_ENTRY' => 'edit-event-profile',
+            'URI_ENTRIES_BY_CONTEXT' => 'events-context',
+            'URI_EDIT_COVER' => 'edit-event-cover',
+            'URI_JOIN_ENTRY' => 'join-event-profile',
+            'URI_JOINED_ENTRIES' => 'joined-events',
+            'URI_MANAGE_COMMON' => 'events-manage',
+            'URI_FAVORITES_LIST' => 'events-favorites',
+
+            'URL_HOME' => 'page.php?i=events-home',
+            'URL_ENTRY_FANS' => 'page.php?i=event-fans',
+            'URL_MANAGE_COMMON' => 'page.php?i=events-manage',
+            'URL_MANAGE_ADMINISTRATION' => 'page.php?i=events-administration',
+
+            'PARAM_AUTO_APPROVE' => 'bx_events_enable_auto_approve',
+            'PARAM_CHARS_SUMMARY' => 'bx_events_summary_chars',
+            'PARAM_NUM_RSS' => 'bx_events_num_rss',
+            'PARAM_NUM_CONNECTIONS_QUICK' => 'bx_events_num_connections_quick',
+            'PARAM_SEARCHABLE_FIELDS' => 'bx_events_searchable_fields',
+            'PARAM_PUBLIC_SBSD' => 'bx_events_public_subscribed_me',
+            'PARAM_PER_PAGE_BROWSE_SHOWCASE' => 'bx_events_per_page_browse_showcase',
+            'PARAM_PER_PAGE_BROWSE_RECOMMENDED' => 'bx_events_per_page_browse_recommended',
+            'PARAM_MMODE' => 'bx_events_members_mode',
+            'PARAM_PAID_JOIN_ENABLED' => true,
+            'PARAM_RECURRING_RESERVE' => 3, // 3 days for recurring payment to be registered
+            'PARAM_PER_PAGE_FOR_FAVORITES_LISTS' => 'bx_events_per_page_for_favorites_lists',
+            'PARAM_USE_IN' => 'bx_events_internal_notifications',
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_events_pics',
+            'OBJECT_STORAGE_COVER' => 'bx_events_pics',
+            'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_events_thumb',
+            'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_events_icon',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR' => 'bx_events_avatar',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR_BIG' => 'bx_events_avatar_big',
+            'OBJECT_IMAGES_TRANSCODER_PICTURE' => 'bx_events_picture',
+            'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_events_cover',
+            'OBJECT_IMAGES_TRANSCODER_COVER_THUMB' => 'bx_events_cover_thumb',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_events_gallery',
+            'OBJECT_VIEWS' => 'bx_events',
+            'OBJECT_VOTES' => 'bx_events',
+            'OBJECT_SCORES' => 'bx_events',
+            'OBJECT_FAVORITES' => 'bx_events',
+            'OBJECT_FEATURED' => 'bx_events',
+            'OBJECT_COMMENTS' => 'bx_events',
+            'OBJECT_NOTES' => 'bx_events_notes',
+            'OBJECT_REPORTS' => 'bx_events',
+            'OBJECT_METATAGS' => 'bx_events',
+            'OBJECT_CATEGORY' => 'bx_events_cats',
+            'OBJECT_FORM_ENTRY' => 'bx_event',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_event_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW_FULL' => 'bx_event_view_full', // for "info" tab on view group page
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_event_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_event_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER' => 'bx_event_edit_cover',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_event_delete',
+            'OBJECT_FORM_ENTRY_DISPLAY_INVITE' => 'bx_event_invite',
+            'OBJECT_FORM_PRICE' => 'bx_events_price',
+            'OBJECT_FORM_PRICE_DISPLAY_ADD' => 'bx_events_price_add',
+            'OBJECT_FORM_PRICE_DISPLAY_EDIT' => 'bx_events_price_edit',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_events_view_actions', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE' => 'bx_events_view_actions_more', // actions menu on view entry page for "more" popup
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_events_view_actions_all', // all actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_events_my', // actions menu on profile entries page
+            'OBJECT_MENU_SUBMENU' => 'bx_events_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_events_view_submenu',  // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'events-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_VIEW_ENTRY_META' => 'bx_events_view_meta', // meta menu on view entry page
+            'OBJECT_MENU_SNIPPET_META' => 'bx_events_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_events_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_PAGE_VIEW_ENTRY' => 'bx_events_view_profile',
+            'OBJECT_PAGE_VIEW_ENTRY_CLOSED' => 'bx_events_view_profile_closed',
+            'OBJECT_PRIVACY_VIEW' => 'bx_events_allow_view_to',
+            'OBJECT_PRIVACY_LIST_VIEW' => 'bx_events_allow_view_favorite_list',
+            'OBJECT_PRIVACY_VIEW_NOTIFICATION_EVENT' => 'bx_events_allow_view_notification_to',
+            'OBJECT_PRIVACY_POST' => 'bx_events_allow_post_to',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_events_administration',
+            'OBJECT_GRID_COMMON' => 'bx_events_common',
+            'OBJECT_GRID_CONNECTIONS' => 'bx_events_fans',
+            'OBJECT_GRID_INVITES' => 'bx_events_invites',
+            'OBJECT_GRID_PRICES_MANAGE' => 'bx_events_prices_manage',
+            'OBJECT_GRID_PRICES_VIEW' => 'bx_events_prices_view',
+            'OBJECT_CONNECTIONS' => 'bx_events_fans',
+            'OBJECT_UPLOADERS_COVER' => array('bx_events_cover_crop'),
+            'OBJECT_UPLOADERS_PICTURE' => array('bx_events_picture_crop'),
+            'OBJECT_PRE_LIST_ROLES' => 'bx_events_roles',
+            'OBJECT_PRE_LIST_PERIOD_UNITS' => 'bx_events_period_units',
+            
+            'BADGES_AVALIABLE' => true,
+            'INVITES_KEYS_LIFETIME' => 86400,
+            'ENABLE_FOR_CONTEXT_IN_MODULES' => array('bx_groups', 'bx_spaces'),
+
+            'EMAIL_INVITATION' => 'bx_events_invitation',
+            'EMAIL_JOIN_REQUEST' => 'bx_events_join_request',
+            'EMAIL_JOIN_CONFIRM' => 'bx_events_join_confirm',
+            'EMAIL_FAN_BECOME_ADMIN' => 'bx_events_fan_become_admin',
+            'EMAIL_ADMIN_BECOME_FAN' => 'bx_events_admin_become_fan',
+            'EMAIL_FAN_REMOVE' => 'bx_events_fan_remove',
+            'EMAIL_FAN_SET_ROLE' => 'bx_events_set_role',
+            'EMAIL_JOIN_REJECT' => 'bx_events_join_reject',
+            'EMAIL_REMINDER' => 'bx_events_reminder',
+
+            'TRIGGER_MENU_PROFILE_VIEW_SUBMENU' => 'trigger_group_view_submenu',
+            'TRIGGER_MENU_PROFILE_SNIPPET_META' => 'trigger_group_snippet_meta',
+            'TRIGGER_MENU_PROFILE_VIEW_ACTIONS' => 'trigger_group_view_actions',
+        	'TRIGGER_PAGE_VIEW_ENTRY' => 'trigger_page_group_view_entry',
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_events_view_actions' => $this->_aMenuItems2MethodsActions,
+                'bx_events_view_actions_more' => $this->_aMenuItems2MethodsActions,
+                'bx_events_view_actions_all' => $this->_aMenuItems2MethodsActions,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'status' => array (
+                    'name' => 'bx-events-status-not-active',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_events_txt_account_pending',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_events_txt_account_suspended',
+                    ),
+                ),
+                'approving' => array (
+                    'name' => 'bx-groups-approving',
+                    'map' => array (
+                        'pending' => array('msg' => '_bx_events_txt_account_pending', 'type' => BX_INFORMER_ALERT),
+                        'hidden' => array('msg' => '_bx_events_txt_status_hidden', 'type' => BX_INFORMER_ERROR),
+                    ),
+                ),
+                'scheduled' => array (
+                    'name' => 'bx-events-scheduled',
+                    'map' => array (
+                        'awaiting' => array('msg' => '_bx_events_txt_scheduled_awaiting', 'type' => BX_INFORMER_ALERT),
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_events_txt_sample_single',
+            	'txt_sample_single_with_article' => '_bx_events_txt_sample_single_with_article',
+            	'txt_sample_comment_single' => '_bx_events_txt_sample_comment_single',
+                'txt_sample_vote_single' => '_bx_events_txt_sample_vote_single',
+                'txt_sample_score_up_single' => '_bx_events_txt_sample_score_up_single',
+                'txt_sample_score_down_single' => '_bx_events_txt_sample_score_down_single',
+                'txt_private_group' => '_bx_events_txt_private_group',
+                'txt_N_fans' => '_bx_events_txt_N_fans',
+                'txt_ntfs_join_invitation' => '_bx_events_txt_ntfs_join_invitation',
+                'txt_ntfs_join_request' => '_bx_events_txt_ntfs_join_request',
+                'txt_ntfs_fan_added' => '_bx_events_txt_ntfs_fan_added',
+            	'txt_ntfs_timeline_post_common' => '_bx_events_txt_ntfs_timeline_post_common',
+                'option_members_mode_multi_roles' => '_bx_events_option_members_mode_multi_roles',
+                'txt_all_entries_in' => '_bx_events_txt_all_entries_in',
+            	'form_field_author' => '_bx_events_form_profile_input_author',
+                'menu_item_title_befriend_sent' => '_bx_events_menu_item_title_befriend_sent',
+                'menu_item_title_unfriend_cancel_request' => '_bx_events_menu_item_title_unfriend_cancel_request',
+                'menu_item_title_befriend_confirm' => '_bx_events_menu_item_title_befriend_confirm',
+                'menu_item_title_unfriend_reject_request' => '_bx_events_menu_item_title_unfriend_reject_request',
+                'menu_item_title_befriend' => '_bx_events_menu_item_title_befriend',
+                'menu_item_title_unfriend' => '_bx_events_menu_item_title_unfriend',
+                'menu_item_title_subscribe' => '_bx_events_menu_item_title_subscribe',
+                'menu_item_title_unsubscribe' => '_bx_events_menu_item_title_unsubscribe',
+            	'grid_action_err_delete' => '_bx_events_grid_action_err_delete',
+            	'grid_txt_account_manager' => '_bx_events_grid_txt_account_manager',
+                'filter_item_active' => '_bx_events_grid_filter_item_title_adm_active',
+                'filter_item_hidden' => '_bx_events_grid_filter_item_title_adm_hidden',
+            	'filter_item_pending' => '_bx_events_grid_filter_item_title_adm_pending',
+            	'filter_item_suspended' => '_bx_events_grid_filter_item_title_adm_suspended',
+            	'filter_item_select_one_filter1' => '_bx_events_grid_filter_item_title_adm_select_one_filter1',
+                'filter_item_select_one_filter2' => '_bx_events_grid_filter_item_title_adm_select_one_filter2',
+            	'menu_item_manage_my' => '_bx_events_menu_item_title_manage_my',
+                'menu_item_manage_all' => '_bx_events_menu_item_title_manage_all',
+                'menu_item_title_become_fan_sent' => '_bx_events_menu_item_title_become_fan_sent',
+                'menu_item_title_leave_group_cancel_request' => '_bx_events_menu_item_title_leave_group_cancel_request',
+                'menu_item_title_become_fan' => '_bx_events_menu_item_title_become_fan',
+                'menu_item_title_leave_group' => '_bx_events_menu_item_title_leave_group',
+                'menu_item_title_become_fan_sent' => '_bx_events_menu_item_title_become_fan_sent',
+                'menu_item_title_become_fan' => '_bx_events_menu_item_title_become_fan',
+            	'txt_all_entries_by_author' => '_bx_events_page_title_browse_by_author',
+                'txt_all_entries_by_context' => '_bx_events_page_title_browse_by_context',
+                'txt_invitation_popup_title' => '_bx_events_txt_invite_popup_title',
+                'txt_invitation_popup_text' => '_bx_events_txt_invite_popup_text',
+                'txt_invitation_popup_accept_button' => '_bx_events_txt_invite_popup_button_accept',
+                'txt_invitation_popup_decline_button' => '_bx_events_txt_invite_popup_button_decline',
+                'txt_invitation_popup_error_invitation_absent' => '_bx_events_txt_invite_popup_error_invitation_absent',
+                'txt_invitation_popup_error_wrong_user' => '_bx_events_txt_invite_popup_error_invitation_wrong_user',
+                'txt_n_unit' => '_bx_events_txt_n_unit',
+                'txt_buy_title' => '_bx_events_grid_action_title_buy_title',
+                'txt_cart_item_title' => '_bx_events_txt_cart_item_title',
+                'txt_cart_item_title_lifetime' => '_bx_events_txt_cart_item_title_lifetime',
+                'txt_subscribe_title' => '_bx_events_grid_action_title_subscribe_title',
+                'popup_title_price_add' => '_bx_events_popup_title_price_add',
+                'popup_title_price_edit' => '_bx_events_popup_title_price_edit',
+                'msg_performed' => '_bx_events_msg_performed',
+                'err_period_unit' => '_bx_events_form_price_input_err_period_unit',
+                'err_price_duplicate' => '_bx_events_err_price_duplicate',
+                'err_cannot_perform' => '_bx_events_err_cannot_perform',
+            ),
+
+        );
+
+        $this->_aJsClasses = array(
+            'main' => 'BxEventsMain',
+            'entry' => 'BxEventsEntry',
+            'manage_tools' => 'BxEventsManageTools',
+            'invite_popup' => 'BxEventsInvitePopup',
+            'prices' => 'BxEventsPrices'
+        );
+
+        $this->_aJsObjects = array(
+            'main' => 'oBxEventsMain',
+            'entry' => 'oBxEventsEntry',
+            'manage_tools' => 'oBxEventsManageTools',
+            'invite_popup' => 'oBxEventsInvitePopup',
+            'prices' => 'oBxEventsPrices'
+        );
+
+        $this->_aGridObjects = array(
+            'common' => $this->CNF['OBJECT_GRID_COMMON'],
+            'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION']
+        );
+    }
+
+}
+
+/** @} */

+ 45 - 0
modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsMenuSnippetMeta.php

@@ -0,0 +1,45 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Events Events
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxEventsMenuSnippetMeta extends BxBaseModGroupsMenuSnippetMeta
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_events';
+
+        parent::__construct($aObject, $oTemplate);
+
+        unset($this->_aConnectionToFunctionCheck['sys_profiles_friends']);
+        unset($this->_aConnectionToFunctionTitle['sys_profiles_friends']);
+    }
+
+    protected function _getMenuItemDateStart($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if ($this->_aContentInfo[$CNF['FIELD_DATE_START']])
+            return $this->getUnitMetaItemText(bx_time_js($this->_aContentInfo[$CNF['FIELD_DATE_START']], BX_FORMAT_DATE_TIME, true));
+        else
+            return false;
+    }
+
+    protected function _getMenuItemDateEnd($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if ($this->_aContentInfo[$CNF['FIELD_DATE_END']])
+            return $this->getUnitMetaItemText(bx_time_js($this->_aContentInfo[$CNF['FIELD_DATE_END']], BX_FORMAT_DATE_TIME, true));
+        else
+            return false;
+    }
+}
+
+/** @} */

+ 115 - 0
modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsMenuViewActionsAll.php

@@ -0,0 +1,115 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Events Events
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+use Spatie\CalendarLinks\Link;
+
+/**
+ * View entry all actions menu
+ */
+class BxEventsMenuViewActionsAll extends BxBaseModGroupsMenuViewActionsAll
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_events';
+
+        parent::__construct($aObject, $oTemplate);
+    }
+
+    public function setContentId($iContentId)
+    {
+        parent::setContentId($iContentId);
+
+        if (!isset($this->_aContentInfo['date_start']) || !$this->_aContentInfo['date_start'] || !isset($this->_aContentInfo['date_end']) || !$this->_aContentInfo['date_end'])
+            return;
+
+        $oDateStart = new DateTime('@' . $this->_aContentInfo['date_start']);
+        $oDateEnd = new DateTime('@' . ($this->_aContentInfo['date_end'] > $this->_aContentInfo['repeat_stop'] ? $this->_aContentInfo['date_end'] : $this->_aContentInfo['repeat_stop']));
+
+        $CNF = $this->_oModule->_oConfig->CNF;
+
+        if ($this->_aContentInfo[$CNF['FIELD_TIMEZONE']]) {
+            $oTz = new DateTimeZone($this->_aContentInfo[$CNF['FIELD_TIMEZONE']]);
+            $oDateStart->setTimezone($oTz);
+            $oDateEnd->setTimezone($oTz);
+        }
+
+        $oICalLink = $oDateStart && $oDateEnd ? Link::create(
+            $this->_aContentInfo[$CNF['FIELD_TITLE']],
+            $oDateStart,
+            $oDateEnd
+        ) : null;
+
+        if (!empty($CNF['OBJECT_METATAGS'])) {
+            $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
+            if ($oMetatags->locationsIsEnabled()) {
+                $sLocation = $oMetatags->locationsString($this->_aContentInfo[$CNF['FIELD_ID']], false);
+                if ($sLocation)
+                    $oICalLink->address($sLocation);
+            }
+        }
+
+        $this->addMarkers([
+            'ical_url' => $oICalLink ? $oICalLink->ics() : '',
+        ]);
+    }
+
+    protected function _getMenuAttrs ($aMenuItem)
+    {
+        $s = parent::_getMenuAttrs ($aMenuItem);
+        if ('ical-export' == $aMenuItem['name']) {
+            $CNF = $this->_oModule->_oConfig->CNF;
+            $s .= ' download="' . title2uri($this->_aContentInfo[$CNF['FIELD_TITLE']]) . '.ics"';
+        }
+        return $s;
+    }
+
+    protected function _getMenuItemJoinEventProfile($aItem)
+    {
+        return $this->_getMenuItemByNameActions($aItem);
+    }
+
+    protected function _getMenuItemEditEventCover($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
+
+    protected function _getMenuItemEditEventProfile($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
+
+    protected function _getMenuItemEditEventPricing($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
+
+    protected function _getMenuItemInviteToEvent($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
+
+    protected function _getMenuItemDeleteEventProfile($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
+
+    protected function _getMenuItemApproveEventProfile($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
+
+    protected function _getMenuItemProfileSetBadges($aItem)
+    {
+        return $this->_getMenuItemByNameActions($aItem);
+    }
+}
+
+/** @} */

+ 493 - 0
modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsModule.php

@@ -0,0 +1,493 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Events Events
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Events profiles module.
+ */
+class BxEventsModule extends BxBaseModGroupsModule implements iBxDolCalendarService 
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+        
+        $CNF = &$this->_oConfig->CNF;
+        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
+            $CNF['FIELD_TIMEZONE'],
+            $CNF['FIELD_JOIN_CONFIRMATION'],
+            $CNF['FIELD_REMINDER']
+        ));
+    }
+
+    public function actionCalendarData()
+    {
+        // check permissions
+        $aSQLPart = array();
+        $iContentId = (int)bx_get('event');
+        $iContextId = (int)bx_get('context_id');
+        
+        if ($iContentId) {
+            $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+            if (CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedView($aContentInfo)) {
+                $this->_oTemplate->displayAccessDenied();
+                exit;
+            }
+            $aSQLPart = array();
+        }
+        else {
+            $oPrivacy = BxDolPrivacy::getObjectInstance($this->_oConfig->CNF['OBJECT_PRIVACY_VIEW']);
+            if($iContextId){
+                if (!$this->serviceIsEnableForContext($iContextId)){
+                    exit;
+                }
+                else{
+                    $aSQLPart = $oPrivacy ? $oPrivacy->getContentByGroupAsSQLPart(- $iContextId) : array();
+                }
+            }
+            else{
+                $aSQLPart = $oPrivacy ? $oPrivacy->getContentPublicAsSQLPart(0, $oPrivacy->getPartiallyVisiblePrivacyGroups()) : array();
+            }
+        }
+
+        // get entries
+        $aEntries = $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), bx_get('event'), $aSQLPart);
+        
+        bx_alert($this->getName(), 'calendar_data', 0, false, array(
+            'event' => $iContentId,
+            'context_id' => $iContextId,
+            'start' => bx_get('start'),
+            'end' =>  bx_get('end'),
+            'sql_part' => &$aSQLPart,
+            'data' => &$aEntries,
+        ));
+        
+        header('Content-Type: application/json; charset=utf-8');
+        echo json_encode($aEntries);
+    }
+    
+    public function serviceIsIcalExportAvaliable($iContentId)
+    {
+        return true;
+        $aContentInfo = $iContentId ? $this->_oDb->getContentInfoById($iContentId) : false;
+        if ($aContentInfo)
+            return false;
+        
+        return $aContentInfo['date_start'] && $aContentInfo['date_end'];
+    }
+
+    public function serviceGetCalendarEntries($iProfileId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $oConn = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
+        $aData = $oConn->getConnectedContent($iProfileId);
+        $aData2 = array(0);
+        foreach($aData as $iProfileId2){
+            $oProfile = BxDolProfile::getInstance($iProfileId2);
+            array_push($aData2, $oProfile->getContentId());
+        }
+        $aSQLPart['where'] = " AND `bx_events_data`.`id` IN(" . implode(',', $aData2) . ")";
+        return $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), null, $aSQLPart);
+	}
+
+    public function serviceGetSafeServices()
+    {
+        $a = parent::serviceGetSafeServices();
+        return array_merge($a, array (
+            'BrowsePastProfiles' => '',
+            'Calendar' => '',
+        ));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-browse Browse
+     * @subsubsection bx_events-browse_upcoming_profiles browse_upcoming_profiles
+     * 
+     * @code bx_srv('bx_events', 'browse_upcoming_profiles', [...]); @endcode
+     * 
+     * Browse upcoming events
+     * 
+     * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
+     * @param $bAjaxPaginate use AJAX paginate or not
+     *
+     * @see BxEventsModule::serviceBrowseUpcomingProfiles
+     */
+    /** 
+     * @ref bx_events-browse_upcoming_profiles "browse_upcoming_profiles"
+     */
+    public function serviceBrowseUpcomingProfiles ($aParams = false)
+    {
+        $bDisplayEmptyMsg = false;
+        if(isset($aParams['empty_message'])) {
+            $bDisplayEmptyMsg = (bool)$aParams['empty_message'];
+            unset($aParams['empty_message']);
+        }
+
+        $bAjaxPaginate = true;
+        if(isset($aParams['ajax_paginate'])) {
+            $bAjaxPaginate = (bool)$aParams['ajax_paginate'];
+            unset($aParams['ajax_paginate']);
+        }
+
+        return $this->_serviceBrowse ('upcoming', $aParams, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-browse Browse
+     * @subsubsection bx_events-browse_upcoming_connected_profiles browse_upcoming_connected_profiles
+     * 
+     * @code bx_srv('bx_events', 'browse_upcoming_connected_profiles', [...]); @endcode
+     * 
+     * Browse upcoming connected (followed) events
+     * 
+     * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
+     * @param $bAjaxPaginate use AJAX paginate or not
+     *
+     * @see BxEventsModule::serviceBrowseUpcomingConnectedProfiles
+     */
+    /** 
+     * @ref bx_events-browse_upcoming_connected_profiles "browse_upcoming_connected_profiles"
+     */
+    public function serviceBrowseUpcomingConnectedProfiles ($aParams = false)
+    {
+        if(!is_array($aParams) || empty($aParams['object']) || empty($aParams['profile']))
+            return '';
+
+        $bDisplayEmptyMsg = false;
+        if(isset($aParams['empty_message'])) {
+            $bDisplayEmptyMsg = (bool)$aParams['empty_message'];
+            unset($aParams['empty_message']);
+        }
+
+        $bAjaxPaginate = true;
+        if(isset($aParams['ajax_paginate'])) {
+            $bAjaxPaginate = (bool)$aParams['ajax_paginate'];
+            unset($aParams['ajax_paginate']);
+        }
+
+        $aDefaults = array(
+            'type' => 'content',
+            'mutual' => false,
+            'profile2' => 0
+        );
+
+        return $this->_serviceBrowse ('upcoming_connected', array_merge($aDefaults, $aParams), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-browse Browse
+     * @subsubsection bx_events-browse_past_profiles browse_past_profiles
+     * 
+     * @code bx_srv('bx_events', 'browse_past_profiles', [...]); @endcode
+     * 
+     * Browse past events
+     * 
+     * @param $bDisplayEmptyMsg show "empty" message or not if nothing found
+     * @param $bAjaxPaginate use AJAX paginate or not
+     *
+     * @see BxEventsModule::serviceBrowsePastProfiles
+     */
+    /** 
+     * @ref bx_events-browse_past_profiles "browse_past_profiles"
+     */
+    public function serviceBrowsePastProfiles ($bDisplayEmptyMsg = false, $bAjaxPaginate = true)
+    {
+        return $this->_serviceBrowse ('past', false, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-browse Browse
+     * @subsubsection bx_events-browse_past_profiles browse_past_profiles_by_params
+     * 
+     * @code bx_srv('bx_events', 'browse_past_profiles_by_params', [...]); @endcode
+     * 
+     * Browse past events
+     * 
+     * @param $aParams array with all parameters
+     *
+     * @see BxEventsModule::serviceBrowsePastProfilesByParams
+     */
+    /** 
+     * @ref bx_events-browse_past_profiles_by_params "browse_past_profiles_by_params"
+     */
+    public function serviceBrowsePastProfilesByParams ($aParams)
+    {
+        $bDisplayEmptyMsg = false;
+        if(isset($aParams['empty_message'])) {
+            $bDisplayEmptyMsg = (bool)$aParams['empty_message'];
+            unset($aParams['empty_message']);
+        }
+
+        $bAjaxPaginate = true;
+        if(isset($aParams['ajax_paginate'])) {
+            $bAjaxPaginate = (bool)$aParams['ajax_paginate'];
+            unset($aParams['ajax_paginate']);
+        }
+        return $this->_serviceBrowse ('past', $aParams, BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-page_blocks Page Blocks
+     * @subsubsection bx_events-calendar calendar
+     * 
+     * @code bx_srv('bx_events', 'calendar', [...]); @endcode
+     * 
+     * Shows event or events calendar
+     * 
+     * @param $aData additional data to point which events to show, leave empty to show all events, specify event's ID in 'event' array key to show calendar for one event only, specify context's ID in 'context_id' array key to show calendar for one context events only. If only one event is specified then it will show calendar only if it's repeating event.
+     * @param $sTemplate template to use to show calendar, or leave empty for default template, possible options: calendar.html, calendar_compact.html
+     * @return HTML string with calendar to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML. On error empty string is returned.
+     *
+     * @see BxEventsModule::serviceCalendar
+     */
+    /** 
+     * @ref bx_events-calendar "calendar"
+     */
+    public function serviceCalendar($aData = array(), $sTemplate = 'calendar.html')
+    {
+        if (isset($aData['event'])) {
+            $aContentInfo = $this->_oDb->getContentInfoById ((int)$aData['event']);
+            if ('' == $aContentInfo['repeat_stop']) // don't display calendar for non repeating events
+                return '';
+        } 
+
+        if (isset($aData['context_id'])) {
+            if (!$this->serviceIsEnableForContext($aData['context_id'])){
+                return '';
+            }                
+        } 
+
+        $oCalendar = new BxTemplCalendar(array(
+            'eventSources' => array (
+                bx_append_url_params(BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'calendar_data', $aData),
+            ),
+        ), $this->_oTemplate);
+
+        $this->_oTemplate->addCss(array('main.css'));
+        return $oCalendar->display($sTemplate);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-other Other
+     * @subsubsection bx_events-process_reminders process_reminders
+     * 
+     * @code bx_srv('bx_events', 'process_reminders'); @endcode
+     * 
+     * Send remiders to event's participants.
+     *
+     * It must be processed once every hour for the proper processing.
+     * @return nothing
+     *
+     * @see BxEventsModule::serviceProcessReminders
+     */
+    /** 
+     * @ref bx_events-process_reminders "process_reminders"
+     */
+    public function serviceProcessReminders()
+    {
+        $iNow = time();
+
+        // get all events for today and tomorrow, since the max reminder is 24 hours
+        $aEntries = $this->_oDb->getEntriesByDate('@' . time(), '@' . (time() + 3600 * getParam('bx_events_reminder_interval')));
+
+        foreach ($aEntries as $a) {
+            if (!$a['reminder'])
+                continue;
+            $iTimestamp = $a['start_utc'] - (3600 * $a['reminder']);
+            if ($iNow > ($iTimestamp - 3600) && $iNow < $iTimestamp)
+                $this->sendReminders($a);
+        }
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_events Events
+     * @subsection bx_events-internal Internal
+     * @subsubsection bx_events-get_timeline_post get_timeline_post
+     *
+     * @code bx_srv('bx_events', 'get_timeline_post', [...]); @endcode
+     * 
+     * Get Timeline post. It's needed for Timeline module.
+     * 
+     * @param $aEvent timeline event array from Timeline module
+     * @return array in special format which is needed specifically for Timeline module to display the data.
+     *
+     * @see BxEventsModule::serviceGetTimelinePost
+     */
+    /** 
+     * @ref bx_events-get_timeline_post "get_timeline_post"
+     */
+    public function serviceGetTimelinePost($aEvent, $aBrowseParams = array())
+    {
+        $a = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
+        if($a === false)
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return $a;
+
+        $CNF = $this->_oConfig->CNF;
+
+        $oDateStart = date_create('@' . $aContentInfo['date_start']);
+        if ($oDateStart)
+            $oDateStart->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
+
+        $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
+        $sLocationString = $oMetatags ? $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false) : false;
+
+        $a['content']['raw'] = $this->_oTemplate->parseHtmlByName('timeline_post.html', [
+            'title' => $a['content']['title'],
+            'title_attr' => bx_html_attribute($a['content']['title']),
+            'url' => $a['content']['url'],
+            'bx_if:date' => [
+                'condition' => $oDateStart,
+                'content' => [
+                    'date' => $oDateStart ? bx_time_js($aContentInfo['date_start'], BX_FORMAT_DATE_TIME) : '',
+                    'date_c' => $oDateStart->format('c'),
+            ]],
+            'bx_if:location' => array(
+                'condition' => !!$sLocationString,
+                'content' => array('location' => $sLocationString),
+            ),
+        ]);
+
+        $a['content']['title'] = '';
+        $a['content']['text'] = '';
+
+        return $a;
+    }
+    
+    public function actionIntervals()
+    {
+        $sAction = bx_get('a');
+        $sMethodName = 'subaction' . ucfirst($sAction);
+        if (!method_exists($this, $sMethodName)) {
+            $this->_oTemplate->pageNotFound();
+            return;
+        }
+        $this->$sMethodName();
+    }
+
+    public function subactionRestore($iContentId = 0)
+    {
+        if (!$iContentId)
+            $iContentId = (int)bx_get('c');
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+
+        if (
+            ($aContentInfo && CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedEdit ($aContentInfo))
+            ||
+            (!$aContentInfo && CHECK_ACTION_RESULT_ALLOWED !== $this->checkAllowedAdd ())
+        ) {
+            $this->_oTemplate->displayAccessDenied();
+            exit;
+        }
+
+        $a = $this->_oDb->getIntervals($iContentId);
+        foreach ($a as $iIntervalId => $r) {
+            $a[$iIntervalId]['file_id'] = $r['interval_id'];
+            $a[$iIntervalId]['repeat_stop'] = bx_process_output ($r['repeat_stop'], BX_DATA_DATE_TS);
+        }
+
+        if ('json' == bx_get('f')) {
+            header('Content-type: text/html; charset=utf-8');
+            echo json_encode($a);
+        }
+    }
+
+    public function subactionDelete()
+    {
+        header('Content-type: text/html; charset=utf-8');
+
+        $iIntervalId = (int)bx_get('id');
+
+        if (!($aContentInfo = $this->_oDb->getContentInfoByIntervalId($iIntervalId))) {
+            echo _t('_sys_request_page_not_found_cpt');
+        }
+        elseif (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedEdit ($aContentInfo))) {
+            echo $sMsg;
+        } 
+        elseif (!$this->_oDb->deleteIntervalById($iIntervalId)) {
+            echo _t('_sys_txt_error_occured');
+        } 
+        else {
+            echo 'ok';
+        }
+    }
+
+    public function checkAllowedIcalExport ($aDataEntry, $isPerformAction = false)
+    {
+        return $aDataEntry['date_start'] && $aDataEntry['date_end'] ? CHECK_ACTION_RESULT_ALLOWED : _t('_sys_txt_access_denied');
+    }
+
+    /**
+     * Send reminder to event's paritcipants
+     * @param $aContentInfo content info
+     * @return number of sent reminders
+     */ 
+    protected function sendReminders($aContentInfo)
+    {
+        $CNF = $this->_oConfig->CNF;
+
+        $oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
+        if (!$oConnection)
+            return false;
+
+        $oGroupProfile = BxDolProfile::getInstanceByContentAndType($aContentInfo[$CNF['FIELD_ID']], $this->getName());
+        if (!$oGroupProfile)
+            return false;
+
+        $aParticipants = $oConnection->getConnectedInitiators($oGroupProfile->id(), true);
+        if (!$aParticipants)
+            return true;
+
+        $oDateBegin = new DateTime();
+        $oDateBegin->setTimestamp($aContentInfo['start_utc']);
+        $oDateBegin->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
+        $sEntryBegin = $oDateBegin->format('r');
+        $sEntryBeginShort = date(getParam('bx_events_short_date_format'), $oDateBegin->getTimestamp());
+        $oDateBegin->setTimezone(new DateTimeZone('UTC'));
+        $sEntryBeginUTC = $oDateBegin->format('c');
+
+        $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
+        $sLocationString = $oMetatags->locationsString($aContentInfo[$CNF['FIELD_ID']], false);
+
+        $iCounter = 0;
+        foreach ($aParticipants as $iProfileId) {
+
+            $b = sendMailTemplate($CNF['EMAIL_REMINDER'], 0, $iProfileId, array(
+                'EntryUrl' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]),
+                'EntryTitle' => $aContentInfo['title'],
+                'EntryBegin' => $sEntryBegin,
+                'EntryBeginShort' => $sEntryBeginShort,
+                'EntryBeginUTC' => $sEntryBeginUTC,
+                'EntryLocation' => $sLocationString ? _t('_bx_events_email_reminder_location', $sLocationString) : '',
+            ), BX_EMAIL_NOTIFY);
+
+            $iCounter += $b ? 1 : 0;
+        }
+        return $iCounter;
+    }
+}
+
+/** @} */

+ 55 - 0
modules/boonex/events/updates/13.0.3_13.0.4/source/classes/BxEventsTemplate.php

@@ -0,0 +1,55 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Events Events
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Groups module representation.
+ */
+class BxEventsTemplate extends BxBaseModGroupsTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        $this->MODULE = 'bx_events';
+        parent::__construct($oConfig, $oDb);
+    }
+
+    function unitVars ($aData, $isCheckPrivateContent = true, $mixedTemplate = false, $aParams = array())
+    {
+        $aVars = parent::unitVars ($aData, $isCheckPrivateContent, $mixedTemplate, $aParams);
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
+
+        $aContentInfo = $this->getModule()->_oDb->getContentInfoById($aData[$CNF['FIELD_ID']]);
+
+        $oDateStart = date_create('@' . $aContentInfo['date_start']);
+        if ($oDateStart)
+            $oDateStart->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
+
+        $oDateEnd = date_create('@' . $aContentInfo['date_end']);
+        if ($oDateEnd)
+            $oDateEnd->setTimezone(new DateTimeZone($aContentInfo['timezone'] ? $aContentInfo['timezone'] : 'UTC'));
+
+        $isPublic = CHECK_ACTION_RESULT_ALLOWED === $this->getModule()->checkAllowedView($aData) || $oPrivacy->isPartiallyVisible($aData[$CNF['FIELD_ALLOW_VIEW_TO']]);        
+        if ($isPublic) {
+            $aVars['bx_if:info']['content']['members'] = $oDateStart->format(getParam('bx_events_short_date_format'));
+        }
+
+        return array_merge($aVars, array(
+			'date_start' => $aData['date_start'] ? $aData['date_start'] : '',
+			'date_start_f' => $oDateStart ? date(getParam('bx_events_short_date_format'), $oDateStart->getTimestamp()) : '',
+			'date_end' => $aData['date_end'] ? $aData['date_end'] : '',
+			'date_end_f' => $oDateEnd ? date(getParam('bx_events_short_date_format'), $oDateEnd->getTimestamp()) : '',
+        ));
+    }
+}
+
+/** @} */

+ 152 - 0
modules/boonex/events/updates/13.0.3_13.0.4/source/install/config.php

@@ -0,0 +1,152 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Events Events
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_events',
+    'title' => 'Events',
+    'note' => 'Events functionality.',
+    'version' => '13.0.4',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/events/',
+    'home_uri' => 'events',
+
+    'db_prefix' => 'bx_events_',
+    'class_prefix' => 'BxEvents',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Events',
+
+    /**
+     * Connections.
+     */
+    'connections' => array(
+    	'sys_profiles_friends' => array ('type' => 'profiles'),
+		'sys_profiles_subscriptions' => array ('type' => 'profiles'),
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+        'trigger_group_snippet_meta',
+        'trigger_group_view_actions',
+    ),
+
+    /**
+     * Page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_group_view_entry', 
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_events_pics'
+    ),
+
+	/**
+     * Transcoders.
+     */
+    'transcoders' => array(
+    	'bx_events_icon', 
+    	'bx_events_thumb', 
+    	'bx_events_avatar', 
+        'bx_events_avatar_big', 
+    	'bx_events_picture', 
+    	'bx_events_cover', 
+    	'bx_events_cover_thumb',
+    	'bx_events_gallery'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_events',
+    	'bx_events_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'process_connections' => 1,
+        'process_deleted_profiles' => 1,
+    	'update_relations' => 1,        
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+    	'process_menu_triggers' => 1,
+    	'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'unregister_transcoders' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+        'bx_timeline',
+        'bx_notifications',
+    ),
+);
+
+/** @} */

+ 51 - 0
modules/boonex/files/updates/13.0.3_13.0.4/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Files',
+    'version_from' => '13.0.3',
+    'version_to' => '13.0.4',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/files/updates/update_13.0.3_13.0.4/',
+    'home_uri' => 'files_update_1303_1304',
+
+    'module_dir' => 'boonex/files/',
+    'module_uri' => 'files',
+
+    'db_prefix' => 'bx_files_',
+    'class_prefix' => 'BxFiles',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Files',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/files/updates/13.0.3_13.0.4/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxFilesUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 135 - 0
modules/boonex/files/updates/13.0.3_13.0.4/source/install/config.php

@@ -0,0 +1,135 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Files Files
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_files',
+    'title' => 'Files',
+    'note' => 'Basic blogging module.',
+    'version' => '13.0.4',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/files/',
+    'home_uri' => 'files',
+
+    'db_prefix' => 'bx_files_',
+    'class_prefix' => 'BxFiles',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Files',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+    
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+    	'trigger_group_view_submenu',
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_files_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+		'bx_files_preview',
+        'bx_files_gallery',
+    ),
+
+	/**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_files',
+    	'bx_files_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications',
+    ),
+
+);
+
+/** @} */

+ 17 - 0
modules/boonex/files/updates/13.0.3_13.0.4/source/template/form_ghost_template.html

@@ -0,0 +1,17 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost flex items-start mt-2">
+    <input type="hidden" name="__name__[]" value="{file_id}" />
+    <div class="bx-base-general-icon-wrapper mr-2">
+        <img src="{file_icon}" class="bx-base-general-icon bx-base-general-icon-{file_id} rounded" />
+    </div>
+    <span class="bx-base-general-uploader-ghost">
+        <b>{file_name}</b>
+    </span>
+</div>
+<script>
+    $('#bx-base-general-intert-to-post-link-{file_id}').show();
+
+    // disable images drag&drop, because resized images address can be reset after some time
+    $(".bx-base-general-icon-{file_id}").bind('dragstart', function(){
+        return false; 
+    });
+</script>

+ 15 - 0
modules/boonex/files/updates/13.0.3_13.0.4/source/template/form_ghost_template_upload.html

@@ -0,0 +1,15 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost flex items-start mt-2">
+    <input type="hidden" name="__name__[]" value="{file_id}" />
+    <div class="bx-base-general-icon-wrapper mr-2">
+        <img src="{file_icon}" class="bx-base-general-icon bx-base-general-icon-{file_id} rounded" />
+    </div>
+    <span class="bx-base-general-uploader-ghost">
+        <div class="font-bold"><bx_text:_bx_files_form_entry_input_title /></div>
+        <div class="bx-form-input-wrapper bx-form-input-wrapper-text mt-1">
+            <input class="bx-def-font-inputs bx-form-input-text block w-full py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-md shadow-sm bg-white dark:bg-gray-900 placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-2 focus:text-gray-900 dark:focus:text-gray-100 focus:ring-blue-500 focus:border-opacity-70 focus:ring-opacity-20 focus:border-blue-500 text-sm text-gray-700 dark:text-gray-300 appearance-none" type="text" value="{file_title_attr}" name="title-{file_id}" />
+        </div>
+        <div class="mt-2">
+            <a class="bx-btn bx-btn-small mr-2" href="javascript:void(0);" onclick="bx_base_general_delete_ghost('{file_id}', '{file_url}', '{file_icon}', ['__editor_id__'], {js_instance_name});"><bx_text:_sys_txt_form_entry_input_picture_delete /></a>
+        </div>
+    </span>
+</div>

+ 51 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Discussions',
+    'version_from' => '13.0.4',
+    'version_to' => '13.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/forum/updates/update_13.0.4_13.0.5/',
+    'home_uri' => 'forum_update_1304_1305',
+
+    'module_dir' => 'boonex/forum/',
+    'module_uri' => 'forum',
+
+    'db_prefix' => 'bx_forum_',
+    'class_prefix' => 'BxForum',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Discussions',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxForumUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 227 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/source/classes/BxForumMenuCategories.php

@@ -0,0 +1,227 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaBaseView UNA Base Representation Classes
+ * @{
+ */
+
+/**
+ * Menu representation.
+ * @see BxDolMenu
+ */
+class BxForumMenuCategories extends BxTemplMenu
+{
+    protected $_iMenuItemsMin;
+    protected $_oModule;
+
+    public function __construct ($aObject, $oTemplate)
+    {
+        parent::__construct ($aObject, $oTemplate);
+
+        $this->_sModule = 'bx_forum';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+        $this->_bDisplayAddons = true;
+    }
+
+    public function getMenuItems ()
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        
+        $aItems = [];
+        
+        $aCategoriest = bx_srv('system', 'categories_list', ['bx_forum_cats', ['show_empty' => true]], 'TemplServiceCategory');
+        
+        if (!($o = BxDolCategory::getObjectInstance('bx_forum_cats')))
+            return $aItems;
+
+		$aCategories = $o->getCategoriesList(false, true);
+        
+		if(!isset($aCategories['bx_repeat:cats']))
+			return $aItems;
+        
+        $iCount = 0;
+        foreach ($aCategories['bx_repeat:cats'] as $sKey => $aCategory) {
+            $iCount +=  $aCategories['bx_repeat:cats'][$sKey]['num'];
+        }
+        
+        $aItems[] =  [
+            'class_add' => 'bx-psmi-show-0' .  (bx_get('category') == '' ? ' bx-menu-item-active' : ''),
+            'name' => 'show-0',
+            'title' => _t('_bx_forum_txt_all_categories'),
+            'link' => BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']),
+            'onclick' => 'javascript:',
+            'attrs' => '',
+            'bx_if:image' => array (
+                'condition' => false,
+                'content' => [],
+            ),
+            'bx_if:image_inline' => array (
+                'condition' => false,
+                'content' => [],
+            ),
+            'bx_if:icon' => array (
+                'condition' => true,
+                'content' => ['icon' => 'swatchbook'],
+            ),
+            'bx_if:icon-a' => array (
+                'condition' => false,
+                'content' => [],
+            ),
+            'bx_if:icon-html' => array (
+                'condition' => false,
+                'content' => [],
+            ),
+            'bx_if:addon' => [
+                'condition' => true,
+                'content' => ['addon' => $iCount]
+            ]
+        ];
+
+        foreach ($aCategories['bx_repeat:cats'] as $sKey => $aCategory) {
+            $aCategoryData = $this->_oModule->_oDb->getCategories(['type' => 'by_category', 'category' => $aCategory['value']]);
+            if(empty($aCategoryData) || (!empty($aCategoryData['visible_for_levels']) && BxDolAcl::getInstance()->isMemberLevelInSet($aCategoryData['visible_for_levels']))) {
+                
+                $aCategories['bx_repeat:cats'][$sKey]['icon'] = $this->_oTemplate->getImage(isset($aCategoryData['icon']) ? $aCategoryData['icon'] : 'folder', array('class' => 'sys-icon sys-colored'));
+                
+                if (!isset($aCategoryData['icon']) || $aCategoryData['icon'] == '')
+                    $aCategoryData['icon'] = 'folder';
+                
+                list($sIcon, $sIconUrl, $sIconA, $sIconHtml) = BxTemplFunctions::getInstance()->getIcon($aCategoryData['icon']);
+                
+                $aItems[] =  [
+                    // TODO
+                    'class_add' => 'bx-psmi-show-' . $aCategories['bx_repeat:cats'][$sKey]['value'] . (bx_get('category') == $aCategories['bx_repeat:cats'][$sKey]['value'] ? ' bx-menu-item-active' : ''),
+                    'name' => 'show-' . $aCategories['bx_repeat:cats'][$sKey]['value'],
+                    'title' => $aCategories['bx_repeat:cats'][$sKey]['name'],
+                    'link' => $aCategories['bx_repeat:cats'][$sKey]['url'],
+                    'onclick' => 'javascript:',
+                    'attrs' => '',
+                    'bx_if:image' => array (
+                        'condition' => (bool)$sIconUrl,
+                        'content' => array('icon_url' => $sIconUrl),
+                    ),
+                    'bx_if:image_inline' => array (
+                        'condition' => false,
+                        'content' => array('image' => ''),
+                    ),
+                    'bx_if:icon' => array (
+                        'condition' => (bool)$sIcon,
+                        'content' => array('icon' => $sIcon),
+                    ),
+                    'bx_if:icon-a' => array (
+                        'condition' => (bool)$sIconA,
+                        'content' => array('icon-a' => $sIconA),
+                    ),
+                    'bx_if:icon-html' => array (
+                        'condition' => (bool)$sIconHtml,
+                        'content' => array('icon' => $sIconHtml),
+                    ),
+                    'bx_if:addon' => [
+                        'condition' => true,
+                        'content' => ['addon' => $aCategories['bx_repeat:cats'][$sKey]['num']]
+                    ]
+                ];
+            }
+        }
+
+        if(empty($aItems) || !is_array($aItems))
+            return $aItems;
+
+        $iMaxNum = count($aItems);
+        $iMenuItemsMin = (int)getParam('bx_forum_visible_categories');
+        if($iMaxNum <= $iMenuItemsMin)
+            return $aItems;
+
+        $mixedCollpsed = $this->getUserChoiceCollapsed();
+        $bCollpsed = $mixedCollpsed === false || $mixedCollpsed == 1;
+
+        for($i = $iMenuItemsMin; $i < $iMaxNum; $i++)
+            $aItems[$i]['class_add'] .= ' bx-mi-aux' . ($bCollpsed ? ' bx-mi-hidden' : '');
+
+        $aShowMoreLinks = [
+            'more' => ['title' => '_sys_show_more', 'icon' => 'chevron-down', 'class' => $bCollpsed ? '' : 'bx-mi-hidden'],
+            'less' => ['title' => '_sys_show_less', 'icon' => 'chevron-up', 'class' => !$bCollpsed ? '' : 'bx-mi-hidden']
+        ];
+
+        foreach($aShowMoreLinks as $sLink => $aLink)
+            $aItems[] = array(
+                'class_add' => 'bx-psmi-show-' . $sLink . ' ' . $aLink['class'],
+                'name' => 'show-' . $sLink,
+                'title' => _t($aLink['title']),
+                'link' => 'javascript:void(0)',
+                'onclick' => 'bx_menu_show_more_less(this, \'' . $this->_sObject . '\', \'.bx-menu-object-' . $this->_sObject . '\')',
+                'attrs' => '',
+                'bx_if:image' => [
+                    'condition' => false,
+                    'content' => ['icon_url' => ''],
+                ],
+                'bx_if:image_inline' => [
+                    'condition' => false,
+                    'content' => ['image' => ''],
+                ],
+                'bx_if:icon' => [
+                    'condition' => true,
+                    'content' => ['icon' => $aLink['icon']],
+                ],
+                'bx_if:icon-html' => [
+                    'condition' => false,
+                    'content' => ['icon-a' => ''],
+                ],
+                'bx_if:icon-a' => [
+                    'condition' => false,
+                    'content' => ['icon-a' => ''],
+                ],
+                'bx_if:addon' => [
+                    'condition' => false,
+                    'content' => []
+                ]
+            );
+
+        return $aItems;
+    }
+
+    protected function getMenuItemsRaw ()
+    {
+        $aItems = $this->_oQuery->getMenuItemsBy(array(
+            'type' => 'set_name', 
+            'set_name' => $this->_aObject['set_name']
+        ));
+
+        $aDuplicates = $this->_oQuery->getMenuItemsBy(array(
+            'type' => 'set_name_duplicates', 
+            'set_name' => $this->_aObject['set_name']
+        ));
+
+        $oProfile = BxDolProfile::getInstance();
+        if(!$oProfile)
+            return array();
+
+        $sModule = $oProfile->getModule();
+
+        $aResult = array();
+        foreach($aItems as $aItem) {
+            if(in_array($aItem['name'], $aDuplicates) && $aItem['module'] != $sModule)
+                continue;
+            
+            $aResult[$aItem['name']] = $aItem;
+        }
+
+        return $aResult;
+    }
+    
+    protected function _getMenuItem($a)
+    {
+        $mixedResult = parent::_getMenuItem($a);
+
+        if($mixedResult !== false && !empty($mixedResult['link']) && strpos($mixedResult['link'], 'javascript:') === false)
+            $mixedResult['link'] = bx_append_url_params($mixedResult['link'], [
+                'owner' => 1
+            ]);
+
+        return $mixedResult;
+    }
+}
+
+/** @} */

+ 263 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/source/classes/BxForumTemplate.php

@@ -0,0 +1,263 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Forum Forum
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Module representation.
+ */
+class BxForumTemplate extends BxBaseModTextTemplate
+{
+    /**
+     * Constructor
+     */
+    function __construct(&$oConfig, &$oDb)
+    {
+        $this->MODULE = 'bx_forum';
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function entryBreadcrumb($aContentInfo, $aTmplVarsItems = array())
+    {
+    	$CNF = &BxDolModule::getInstance($this->MODULE)->_oConfig->CNF;
+
+        $oPermalink = BxDolPermalinks::getInstance();
+        $oCategory = BxDolCategory::getObjectInstance($CNF['OBJECT_CATEGORY']);
+
+    	$aTmplVarsItems = array(array(
+        	'url' => bx_append_url_params($oPermalink->permalink('page.php?i=' . $CNF['URI_CATEGORY_ENTRIES']), array(
+        		'category' => $aContentInfo[$CNF['FIELD_CATEGORY']]
+        	)),
+        	'title' => $oCategory->getCategoryTitle($aContentInfo[$CNF['FIELD_CATEGORY']])
+        ), array(
+        	'url' => $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]),
+        	'title' => bx_process_output($aContentInfo[$CNF['FIELD_TITLE']])
+        ));
+
+    	return parent::entryBreadcrumb($aContentInfo, $aTmplVarsItems);
+    }
+
+    public function entryParticipants($aContentInfo, $iMaxVisible = 2, $sFloat = 'left')
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        $iAuthorId = $aContentInfo[$CNF['FIELD_AUTHOR']];
+        $aParticipants = $this->_oDb->getComments(array('type' => 'author_comments', 'object_id' => $aContentInfo[$CNF['FIELD_ID']]));
+        $aParticipants[$iAuthorId] = !empty($aParticipants[$iAuthorId]) ? $aParticipants[$iAuthorId] + 1 : 1;
+
+        // sort participants: first - current user, second - last replier, third - author, all others sorted by max number of posts
+        $aParticipants = $oModule->sortParticipants($aParticipants, $aContentInfo['lr_profile_id'], $iAuthorId);
+        $iParticipantsNum = count($aParticipants);
+
+        // prepare template variables
+        $aVarsPopup = array (
+            'float' => 'none',
+            'bx_repeat:participants' => array(),
+            'bx_if:participants_more' => array(
+                'condition' => false,
+                'content' => array(),
+            ),
+        );
+        $aVars = array (
+            'float' => $sFloat,
+            'bx_repeat:participants' => array(),
+            'bx_if:participants_more' => array(
+                'condition' => $iParticipantsNum > $iMaxVisible,
+                'content' => array(
+                    'popup' => '',
+                    'title_more' => _t('_bx_forum_more', $iParticipantsNum - $iMaxVisible),
+                    'float' => $sFloat,
+                    'id' => $this->MODULE . '-popup-' . $aContentInfo[$CNF['FIELD_ID']],
+                ),
+            ),
+        );
+        $i = 0;
+        foreach ($aParticipants as $iProfileId => $iComments) {
+            $oProfile = BxDolProfile::getInstanceMagic($iProfileId);
+
+            $aParticipant = array (
+                'id' => $oProfile->id(),
+                'unit' => $oProfile->getUnit(0, array('template' => 'unit_wo_info')),
+                'float' => $sFloat,
+                'class' => $iAuthorId == $iProfileId ? 'bx-forum-participant-author' : '',
+            	'bx_if:replies_count' => array(
+            		'condition' => $iComments > 0,
+            		'content' => array(
+            			'count' => $iComments
+            		)
+            	),
+                'bx_if:last_replier' => array (
+                    'condition' => ($aContentInfo['lr_profile_id'] == $iProfileId),
+                    'content' => array (
+                        'id' => $oProfile->id(),
+                        'title' => bx_html_attribute(_t('_bx_forum_participant_last_replier')),
+                    ),
+                ),
+                'bx_if:author'  => array (
+                    'condition' => $iAuthorId == $iProfileId,
+                    'content' => array (
+                        'id' => $oProfile->id(),
+                        'title' => bx_html_attribute(_t('_bx_forum_participant_author')),
+                    ),
+                ),
+            );
+
+            if ($i < $iMaxVisible)
+                $aVars['bx_repeat:participants'][] = $aParticipant;
+            if ($i >= $iMaxVisible)
+                $aVarsPopup['bx_repeat:participants'][] = $aParticipant;
+
+            ++$i;
+        }
+
+        if ($aVarsPopup['bx_repeat:participants']) {
+            $aVars['bx_if:participants_more']['content']['popup'] = BxTemplFunctions::getInstance()->transBox('', '<div class="bx-def-padding">' . $this->parseHtmlByName('participants.html', $aVarsPopup) . '</div>');
+        }
+
+        return $this->parseHtmlByName('participants.html', $aVars);
+    }
+
+	function getEntryAuthor($aRow)
+    {
+    	$oProfileAuthor = BxDolProfile::getInstanceMagic($aRow['author']);
+
+    	return $this->parseHtmlByName('entry-author.html', array(
+			'unit' => $oProfileAuthor->getUnit(0, array('template' => 'unit_wo_info')),
+    	));
+    }
+
+    function getEntryPreview($aRow, $aParams = [])
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        $oProfileLast = BxDolProfile::getInstanceMagic($aRow['lr_profile_id']);
+
+        $sTitle = $aRow[$CNF['FIELD_TITLE']];
+
+        $aMetas = array('main' => false, 'counters' => false, 'reply' => false);
+        foreach(array_keys($aMetas) as $sMeta) {
+            $sKey = 'OBJECT_MENU_SNIPPET_META_' . strtoupper($sMeta);
+            if(empty($CNF[$sKey]))
+                continue;
+
+            $oMenuMeta = BxDolMenu::getObjectInstance($CNF[$sKey], $this);
+            if(!$oMenuMeta) 
+                continue;
+
+            $oMenuMeta->setContentId($aRow[$CNF['FIELD_ID']]);
+            $sMenuMeta = $oMenuMeta->getCode();
+            if(empty($sMenuMeta))
+                continue;
+
+            $aMetas[$sMeta] = array(
+                'content' => $sMenuMeta
+            );
+        }
+        
+        $oObject = isset($CNF['OBJECT_COMMENTS']) ? BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $aRow[$CNF['FIELD_ID']]) : null;
+        $sParticipants = $oObject ? $oObject->getCounter(['show_counter_empty' => true, 'show_counter' => false, 'show_counter_style' => 'simple', 'dynamic_mode' => true, 'caption' => '', 'show_icon' => false, 'caption_empty' => '']) : '';
+        
+        $sImage = '';
+        $mixedImage = $this->_getHeaderImage($aRow);
+        if($mixedImage !== false) {
+            if(!empty($mixedImage['object']))
+                $o = BxDolStorage::getObjectInstance($mixedImage['object']);
+            else if(!empty($mixedImage['transcoder']))
+                $o = BxDolTranscoder::getObjectInstance($mixedImage['transcoder']);
+
+            if($o)
+                $sImage = $o->getFileUrlById($mixedImage['id']);
+        }
+
+        return $this->parseHtmlByName('entry-preview.html', array(
+            'bx_if:show_stick' => array(
+                'condition' => (int)$aRow[$CNF['FIELD_STICK']] == 1,
+                'content' => array()
+            ),
+            'bx_if:show_lock' => array(
+                'condition' => (int)$aRow[$CNF['FIELD_LOCK']] == 1,
+                'content' => array()
+            ),
+            'url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $oModule->_oConfig->CNF['URI_VIEW_ENTRY'] . '&id=' . $aRow[$CNF['FIELD_ID']]),
+            'title' => $sTitle ? $sTitle : _t('_Empty'),
+            'participants' => $sParticipants,
+            'badges' => $this->_oModule->serviceGetBadges($aRow[$CNF['FIELD_ID']]),
+            'image' => $sImage,
+            'bx_if:meta_main' => array(
+                'condition' => $aMetas['main'] !== false && (!isset($aParams['show_meta_main']) || $aParams['show_meta_main']),
+                'content' => $aMetas['main']
+            ),
+            'bx_if:image' => array(
+                'condition' => $sImage != '',
+                'content' => ['image' => $sImage]
+            ),
+            
+            'bx_if:meta_counters' => array(
+                'condition' => $aMetas['counters'] !== false && (!isset($aParams['show_meta_counters']) || $aParams['show_meta_counters']),
+                'content' => $aMetas['counters']
+            ),
+            'bx_if:meta_reply' => array(
+                'condition' => $aMetas['reply'] !== false && (!isset($aParams['show_meta_reply']) || $aParams['show_meta_reply']),
+                'content' => $aMetas['reply']
+            )
+        ));
+    }
+    
+    public function getJsCode($sType, $aParams = array(), $mixedWrap = true)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        if ($sType == 'main'){
+            $aParams = array_merge(array(
+                'sObjNameGrid' => $CNF['OBJECT_GRID'],
+            ), $aParams);
+        }
+        return parent::getJsCode($sType, $aParams);
+    }
+
+    function getAuthorDesc ($aData, $oProfile)
+    {
+        return '';
+    }
+
+    function getAuthorAddon ($aData, $oProfile)
+    {
+        return '';
+    }
+    
+    protected function getUnit ($aData, $aParams = array())
+    {
+        $aTmplVars = parent::getUnit($aData, $aParams);
+        
+        $CNF = $this->_oModule->_oConfig->CNF;
+        
+        $oCategory = BxDolCategory::getObjectInstance($CNF['OBJECT_CATEGORY']);
+        
+        $sIcon = $this->_oModule->_oTemplate->parseHtmlByName('default_category.html', []);
+        
+        $aCategoryData = $this->_oModule->_oDb->getCategories(array('type' => 'by_category', 'category' => $aData[$CNF['FIELD_CATEGORY']]));
+
+        if(isset($aCategoryData['icon']))
+            $sIcon = $this->getImage($aCategoryData['icon'], array('class' => 'sys-icon'));
+        
+        $oProfile = BxDolProfile::getInstanceMagic($aData[$CNF['FIELD_AUTHOR']]);
+        $aTmplVars['author'] = $oProfile->getUnit();
+        $aTmplVars['category'] = $oCategory->getCategoryTitle($aData[$CNF['FIELD_CATEGORY']]);
+        $aTmplVars['category_icon'] = $sIcon;
+        $aTmplVars['bx_if:thumb']['content']['badges'] = $aTmplVars['badges'];
+        $aTmplVars['bx_if:no_thumb']['content']['badges'] = $aTmplVars['badges'];
+        $aTmplVars['bx_if:no_thumb']['content']['title'] = $aTmplVars['title'];
+        $aTmplVars['bx_if:no_thumb']['content']['summary_attr'] = $aTmplVars['bx_if:thumb']['content']['summary_attr'];
+
+        return $aTmplVars;
+    }
+}
+
+/** @} */

+ 149 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/source/install/config.php

@@ -0,0 +1,149 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Forum Forum
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_forum',
+    'title' => 'Discussions',
+    'note' => 'Discussions module.',
+    'version' => '13.0.5',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/forum/',
+    'home_uri' => 'forum',
+
+    'db_prefix' => 'bx_forum_',
+    'class_prefix' => 'BxForum',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Discussions',
+    
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_profile_view_entry',
+    ),
+    
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        'trigger_group_view_submenu'
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_forum_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_forum_preview',
+        'bx_forum_gallery',
+        'bx_forum_cover',
+        
+        'bx_forum_preview_photos',
+        'bx_forum_gallery_photos',
+        'bx_forum_view_photos',
+
+        'bx_forum_videos_poster',
+        'bx_forum_videos_poster_preview',
+        'bx_forum_videos_mp4',
+        'bx_forum_videos_mp4_hd',
+        
+        'bx_forum_preview_files',
+        'bx_forum_gallery_files',
+        
+        'bx_forum_preview_cmts',
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_forum',
+    	'bx_forum_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+	'enable_success' => array(
+    	'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+);
+
+/** @} */

+ 581 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/source/template/css/main.css

@@ -0,0 +1,581 @@
+/*-- Participants --*/
+.bx-forum-participants {
+    position:relative;
+}
+.bx-forum-participants.left,
+.bx-forum-participants.none {
+    float: left;
+}
+.bx-forum-participants.right {
+    float: right;
+}
+.bx-forum-participant {
+    position: relative;
+    display: block;
+}
+.bx-forum-participants.left .bx-forum-participant,
+.bx-forum-participants.none .bx-forum-participant {
+    float: left;
+    margin-right: 0.5rem;
+}
+.bx-forum-participants.left .bx-forum-participant:last-child,
+.bx-forum-participants.none .bx-forum-participant:last-child {
+    margin-right: 0;
+}
+.bx-forum-participants.right .bx-forum-participant {
+    float: right;
+    margin-left: 0.5rem;
+}
+.bx-forum-participants.right .bx-forum-participant:last-child {
+    margin-left: 0;
+}
+
+.bx-forum-participant-alert-last-replier {
+    left:0;
+    right:auto;
+}
+
+.bx-forum-participant-alert-author {
+    left:0;
+    right:auto;
+    top:auto;
+    bottom:0;
+}
+
+/*-- Replies --*/
+.cmt.bx-def-box .cmts.cmts-margin {
+    margin-top: 0px;
+}
+.cmt-attached-preview.bx-forum-attached-preview {
+    display: block;
+    float: none;
+
+    width: auto;
+    height: 2rem;
+    line-height: 2rem;
+    white-space: nowrap;
+
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+.cmt-attached-preview.bx-forum-attached-preview img,
+.cmt-attached-preview.bx-forum-attached-preview .sys-icon {
+    display: inline-block;
+    vertical-align: middle;
+
+    width: 2rem;
+    height: 2rem;
+}
+.cmt-attached-preview.bx-forum-attached-preview .sys-icon {
+    text-align: center;
+    font-size: 1.25rem;
+}
+
+/*-- Preview --*/
+.bx-forum-preview {
+    position:relative;
+}
+
+.bx-forum-title {    
+    padding-right:2em;
+    white-space:nowrap;    
+    text-overflow:ellipsis;
+    overflow:hidden;
+}
+
+/*-- Grid --*/
+.bx-forum-grid .bx-grid-table tr.bx-def-color-bg-hl {
+    background-color: transparent;
+}
+
+.bx-forum-grid-field-replies .bx-def-unit-alert-middle {
+    position:static;
+    display:inline-block;
+    vertical-align:middle;
+}
+
+.bx-forum-grid-field-replies > span {
+    vertical-align:middle;
+}
+
+.bx-forum-grid-field-replies {
+    white-space:nowrap;
+}
+
+.bx-forum-grid-field-label {
+    display:inline-block;
+}
+
+.bx-forum-preview .bx-forum-grid-field-label {
+    position: absolute;
+    right: 0;
+    top: 0;
+}
+#bx-forum-snippet-meta-main{
+    overflow: hidden;
+    display: flex;
+    grid-gap: 0.25rem;
+}
+.bx-forum-preview .bx-def-unit-info {
+    line-height:1.15em;
+}
+
+.bx-grid-table-cell-author {
+    vertical-align: top;
+}
+
+.bx-grid-table-cell-author .bx-base-pofile-unit-wo-info {
+	display: inline-block;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-title {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-title a {
+    display: inline-block;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-title a,
+.bx-forum-grid-preview .bx-forum-gp-text {
+    font-size: 1rem; 
+    line-height: 125%; 
+    font-weight: 600; 
+}
+
+.bx-forum-grid-preview .bx-forum-gp-title .sys-icon,
+.bx-forum-grid-preview .bx-forum-gp-text .sys-icon {
+    margin-right:0.25rem;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top {
+    -webkit-justify-content: space-between;
+    justify-content: space-between;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta .bx-menu-custom.bx-menu-custom-hor {
+    margin: 0;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-menu-custom.bx-menu-custom-hor {
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-flex-wrap: nowrap;
+    flex-wrap: nowrap;
+
+    max-width: 100%;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-menu-custom.bx-menu-custom-hor li {
+    -webkit-flex: 0 0 auto;
+    -ms-flex: 0 0 auto;
+    flex: 0 0 auto;
+    
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-menu-custom.bx-menu-custom-hor li.bx-menu-item-reply-text {
+    -webkit-flex-shrink: 1;
+    flex-shrink: 1;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-menu-custom.bx-menu-custom-hor li .bx-base-general-unit-meta-item {
+    display: contents;
+}
+.bx-layout-col.bx-layout-column-thin .bx-forum-grid-preview .bx-forum-gp-meta .bx-def-media-phone-hide {
+    display: none;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .sys-action {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .cmt-counter div.cmt-counter-icon,
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .cmt-counter div.bx-base-pofile-unit-wo-info {
+    margin-left: -4px;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .cmt-counter .bx-def-icon-size {
+    width: 1.0rem;
+    height: 1.0rem;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .cmt-counter .bx-def-icon-size,
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .cmt-counter p.bx-base-pofile-unit-thumb.bx-def-icon-size {
+    line-height: normal;
+    font-size: 0.6rem;
+}
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-top .bx-forum-gpm-counters .cmt-counter div.cmt-counter-icon .sys-icon {
+    font-size: 0.6rem;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-base-pofile-unit {
+    width: auto;
+    margin: 0;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-def-icon-size {
+    width: 1.0rem;
+    height: 1.0rem;
+
+    line-height: 0.875rem;
+    font-size: 0.6rem;
+}
+.bx-forum-grid-preview .bx-menu-item-date .text-sm{
+    font-size: 12px;
+    font-weight: 500;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-def-icon-size-min-height {
+    min-height: 1.0rem;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-def-icon-size-max-height {
+    max-height: 1.0rem;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-def-icon-size-left-indent {
+    margin-left: 1.25rem;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-def-unit-img .bx-base-pofile-unit-thumb {
+    display: block;
+    border-width: 1px;
+}
+
+.bx-forum-grid-preview .bx-forum-gp-meta.bx-forum-gpm-bottom .bx-forum-gpm-reply .bx-menu-item-reply-author .bx-base-pofile-unit-online {
+    display: none;
+}
+
+.bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li > span {
+    position: relative;
+    display: inline-block;
+    vertical-align: top;
+    height: 1.5rem;
+    margin-top: 0;
+    margin-bottom: 0;
+    border-width: 0px;
+    line-height: 1.5rem;
+}
+.bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li a {
+    display: inline-block;
+}
+.bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li .sys-icon:not(.cmt-counter-icon) {
+    width: 1.0rem;
+    height: 1.0rem;
+    text-align: center;
+    line-height: 1.0rem;
+    vertical-align: baseline;
+}
+.bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li .cmt-element-holder,
+.bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li .cmt-counter-holder {
+    line-height: normal;
+}
+
+.bx-forum-category-list-item a{
+    display: flex;
+    align-items: center;
+}
+.bx-forum-category{
+    display: flex;
+    line-height: initial;
+    font-weight: 500;
+    color: #111928;
+}
+.bx-forum-category-list-item-selected{
+    background:  #F3F4F6;
+    border-radius: 8px;
+}
+.dark .bx-forum-category-list-item-selected{
+	background-color: rgba(55, 65, 81, 0.5) !important;
+}
+.bx-forum-icon{
+    min-width: 1.5rem;
+    height: 1.5rem;
+    text-align: center;
+    line-height: 1.7rem;
+    font-size: 1.25rem;
+}
+.bx-forum-icon svg,
+.bx-forum-icon .sys-icon{
+    width: 1.5rem;
+    height: 1.5rem;
+    border-radius: 2rem;
+    display: block;
+}
+.bx-forum-icon img.sys-icon{
+    display: block !important;
+}
+.bx-forum-icon i.sys-icon{
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+}
+.bx-forum-thumb img{
+    border-radius: 500px;
+}
+.bx-forum-thumb .sys-icon{
+    color: #111928;
+    font-size: 1.25rem;
+}
+.dark .bx-forum-thumb .sys-icon{
+    color: rgb(209 213 219);
+}
+.bx-forum-thumb img.sys-icon {
+    width: 1.5rem;
+    height: 1.5rem;
+}
+.bx-forum-thumb .sys-icon-svg{
+    width: 1.5rem;
+    height: 1.5rem;
+}
+
+.bx-forum-grid-status{
+    display: flex;
+}
+.bx-forum-status-0{
+    color: rgb(239, 68, 68);
+    font-weight: 500;
+}
+.bx-forum-status-0:hover{
+    background-color: rgb(239, 68, 68, 0.2);
+}
+.bx-forum-status-1{
+    font-weight: 500;
+    color: rgb(34, 197, 94);
+}
+.bx-forum-status-1:hover{
+    background-color: rgba(34, 197, 94, 0.2);
+}
+#bx-grid-table-bx_forum tr{
+    border-bottom: 1px solid #F4F4F5
+}
+.dark #bx-grid-table-bx_forum tr{
+    border-bottom: 1px solid rgb(55 65 81 / 0.5);;
+}
+#bx-grid-table-bx_forum tr:last-child{
+	border-bottom: none;
+}
+.bx-forum-wrapper .bx-base-text-unit-gallery .bx-menu-item-score{
+    display: none;
+}
+.bx-grid-table-cell-participants .sys-action-counter-iconset .ml-2
+{
+    display: none;
+}
+.bx-grid-table-cell-participants .cmt-counter{
+    float: right;
+}
+#bx-grid-table-bx_forum td{
+    vertical-align: middle !important;
+}
+.bx-forum-grid td{
+    vertical-align: top;
+    padding: 0px !important;
+}
+.bx-forum-grid tr:hover{
+    cursor: pointer;
+}
+.bx-forum-grid .bx-grid-table-wrapper2{
+    margin-left: -1rem;
+    margin-right: -1rem;
+    width:calc(100% + 2rem);
+}
+.bx-forum-grid tr td:first-child{
+    padding-left: 0rem;
+}
+.bx-forum-grid tr td:last-child{
+    padding-right: 0rem;
+}
+.bx-forum-grid tr:hover td:first-child{
+    border-radius: 0.375rem 0 0 0.375rem;
+}
+.bx-forum-grid tr:hover td:last-child{
+    border-radius: 0 0.375rem 0.375rem 0;
+}
+.bx-media-phone .bx-forum-grid {
+    width: 100%;
+    min-width:inherit !important;
+}
+
+.bx-media-phone .bx-forum-grid tr{
+    display: grid;
+	grid-template-areas:
+    "text text"
+	"participants rating";
+	
+    grid-template-rows: auto auto;
+	grid-template-columns: auto auto;
+    margin-bottom: 0.5rem;
+}
+
+.bx-media-phone .bx-forum-grid table{
+    width: 100% !important;
+    min-width: inherit !important;
+    max-width: 100% !important;
+    overflow: hidden;
+    display: block;
+}
+.bx-media-phone .bx-forum-grid td{
+    width: auto !important;
+}
+
+.bx-media-phone .bx-forum-grid .bx-grid-table-cell-category{
+    grid-area: category;
+    display: none;
+}
+.bx-media-phone .bx-forum-grid .bx-grid-table-cell-text{
+    grid-area: text;
+    padding-bottom: 0px;
+    overflow: hidden;
+    padding-top: 0px;
+}
+.bx-media-phone .bx-forum-grid .bx-grid-table-cell-participants{
+    grid-area: participants;
+    padding-top: 0px;
+    display: flex;
+    align-items: center;
+}
+.bx-media-phone .bx-forum-grid .bx-grid-table-cell-rating{
+    grid-area: rating;
+    text-align: right;
+    margin-right: 1rem;
+    padding-top: 0px;
+}
+.bx-media-phone .bx-forum-gpm-main{
+    margin-bottom: 0.5rem;
+    width: 100%;
+}
+.bx-media-phone .bx-forum-gpm-main UL{
+    width: 100%;
+    justify-content: space-between;
+}
+.bx-media-phone .bx-forum-gpm-main UL LI:nth-child(n+4){
+    display: none;
+}
+
+.bx-media-phone .bx-grid-table-cell-participants .cmt-counter{
+    float:none
+}
+/* unit */
+.bx-forum-unit .bx-base-text-unit-title h2{
+    font-size: 1rem;
+    line-height: 1.5;
+    font-weight: 500;
+    color: rgb(17,24,29);
+}
+.bx-forum-unit .bx-base-general-unit-meta-item{
+    font-size: 0.875rem !important; 
+    color:rgb(107,114,128) !important;
+}
+.bx-forum-unit .bx-base-text-unit-no-thumb{
+    background: url("data:image/svg+xml,%3Csvg width='16' height='20' viewBox='0 0 16 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%239C92AC' fill-opacity='0.4' fill-rule='evenodd'%3E%3Cpath d='M8 0v20L0 10M16 0v10L8 0M16 10v10H8'/%3E%3C/g%3E%3C/svg%3E"), linear-gradient(90deg, #3F83F8 0%, #0694A2 100%);
+    text-align: left;
+    color:#fff;
+    border-radius: 7px 7px 0 0;
+}
+.bx-forum-unit .bx-base-text-unit-title{
+    white-space: normal;
+}
+.bx-forum-grid .bx-grid-header-controls-counter{
+    display: none;
+}
+.bx-forum-grid .bx-grid-header-controls-filter{
+    display: flex;
+    width: 100%;
+}
+.bx-forum-grid #bx-form-element-search{
+    flex-grow: 3;
+}
+.bx-forum-unit.bx-base-text-unit-gallery .bx-base-text-unit-info .bx-base-pofile-unit A,
+.bx-forum-unit.bx-base-text-unit-gallery .bx-base-text-unit-title A{
+    color:#fff !important;
+}
+.bx-forum-unit .bx-base-text-unit-info .bx-base-pofile-unit .bx-def-unit-info{
+    text-align: left;
+}
+.bx-forum-unit .bx-base-pofile-unit{
+    margin-bottom: 0px;
+    margin-right: 0px;
+}
+.bx-base-unit-showcase.bx-forum-unit{
+    display: inline-block;
+}
+/* one item */
+.bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(1) {
+    width: 100% !important;
+}
+/* two items */
+.bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(2),
+.bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(2) ~ .bx-forum-unit {
+    width: 50%  !important;
+}
+/* 3 items or more */
+.bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(3),
+.bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(3) ~ .bx-forum-unit {
+    width: 33.3333%;
+}
+.bx-media-tablet .bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(3),
+.bx-media-tablet .bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(3) ~ .bx-forum-unit {
+    width: 50%;
+}
+.bx-media-phone .bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(3),
+.bx-media-phone .bx-base-unit-showcase-wrapper .bx-forum-unit:first-child:nth-last-child(3) ~ .bx-forum-unit {
+    width: 100%;
+}
+
+.bx-forum-grid .sys-action-counter-label.bx-score-counter-label{
+	padding: 0px !important;
+}
+.bx-forum-grid .sys-action-counter-iconset .sys-action-counter-text{
+    display: none;
+}
+
+
+
+
+/* ---------------new meta menu need to move incore*/
+
+.bx-menu-meta-icon img,
+.bx-menu-meta-icon svg{
+    width: 1rem ;
+    height: 1rem !important;
+    border-radius: 1rem ;
+    display: block;
+}
+.bx-menu-meta-icon .sys-icon-emoji{
+    font-size: 0.8rem ;
+}
+
+.bx-menu-meta-item-ex.bx-menu-meta-item-ex-no-bg{
+    background: none !important;
+}
+.bx-menu-meta-item-ex.bx-menu-meta-item-ex-no-pad{
+    padding: 0px !important;
+}
+.bx-menu-meta-item-ex{
+    margin-right: 0.5rem !important;
+}
+.bx-forum-category-list{
+	margin: -0.75rem !important;
+	margin-top: 0px !important;
+}
+.bx-menu-meta-item-ex span:nth-child(2) {
+    margin-left: 0.375rem;
+}
+

+ 30 - 0
modules/boonex/forum/updates/13.0.4_13.0.5/source/template/unit_gallery.html

@@ -0,0 +1,30 @@
+<div onclick="location.href='__content_url__'" class="__class__ bx-base-text-unit bx-forum-unit bx-base-text-unit-gallery bx-def-gal-unit-size flex flex-col w-full p-2 box-border relative inline-block cursor-pointer">
+    <div class="bg-white dark:bg-gray-800 shadow ring-1 ring-gray-300 dark:ring-gray-700 rounded-md xl:mx-auto h-full">
+        <div class="h-full space-y-4 p-1 pb-4 flex flex-col justify-between">
+            <bx_if:thumb>
+                <a href="__content_url__" title="__summary_attr__">
+                    <img class="flex grow-0 w-full aspect-video overflow-y-auto align-top  object-cover rounded" src="__gallery_url__" alt="">
+                </a>  
+            </bx_if:thumb>
+            <div class="grow-none px-3 mt-4 text-lg leading-tight font-semibold text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white">
+                <a href="__content_url__" title="__summary_attr__" class=" text-lg leading-tight font-semibold text-gray-600 group-hover:text-gray-900 dark:text-gray-300 dark:group-hover:text-white">__title__</a>
+            </div>               
+            <bx_if:no_thumb>  
+                <div class="grow relative rounded w-full max-w-full sm:aspect-video overflow-hidden font-normal text-sm  text-gray-500 group-hover:text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-300">
+                    <div class="absolute top-auto bottom-0  w-full h-1/4 bg-gradient-to-b from-white/0 to-white dark:from-gray-900/0 dark:to-gray-800"></div>
+                    <div class=" px-3">__summary_plain__</div>
+                </div>
+            </bx_if:no_thumb>
+            <div class="px-3">
+                __badges__
+            </div>
+            <bx_if:meta>
+                <div class="bx-base-general-unit-meta flex grow-0 px-2">
+                    <div class="inline-flex flex-wrap text-xs font-medium">
+                        __meta__
+                    </div>
+                </div>
+            </bx_if:meta>
+        </div>
+    </div>
+</div>

+ 51 - 0
modules/boonex/groups/updates/13.0.2_13.0.3/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Groups',
+    'version_from' => '13.0.2',
+    'version_to' => '13.0.3',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/groups/updates/update_13.0.2_13.0.3/',
+    'home_uri' => 'groups_update_1302_1303',
+
+    'module_dir' => 'boonex/groups/',
+    'module_uri' => 'groups',
+
+    'db_prefix' => 'bx_groups_',
+    'class_prefix' => 'BxGroups',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Groups',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/groups/updates/13.0.2_13.0.3/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxGroupsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 152 - 0
modules/boonex/groups/updates/13.0.2_13.0.3/source/install/config.php

@@ -0,0 +1,152 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Groups Groups
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_groups',
+    'title' => 'Groups',
+    'note' => 'Basic group profiles functionality.',
+    'version' => '13.0.3',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/groups/',
+    'home_uri' => 'groups',
+
+    'db_prefix' => 'bx_groups_',
+    'class_prefix' => 'BxGroups',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Groups',
+
+    /**
+     * Connections.
+     */
+    'connections' => array(
+    	'sys_profiles_friends' => array ('type' => 'profiles'),
+		'sys_profiles_subscriptions' => array ('type' => 'profiles'),
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+        'trigger_group_snippet_meta',
+        'trigger_group_view_actions',
+    ),
+
+    /**
+     * Page triggers.
+     */
+    'page_triggers' => array (
+    	'trigger_page_group_view_entry', 
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_groups_pics'
+    ),
+
+	/**
+     * Transcoders.
+     */
+    'transcoders' => array(
+    	'bx_groups_icon', 
+    	'bx_groups_thumb', 
+    	'bx_groups_avatar', 
+        'bx_groups_avatar_big', 
+    	'bx_groups_picture', 
+    	'bx_groups_cover', 
+    	'bx_groups_cover_thumb',
+        'bx_groups_gallery'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_groups',
+    	'bx_groups_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'process_connections' => 1,
+        'process_deleted_profiles' => 1,
+    	'update_relations' => 1,        
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+    	'process_menu_triggers' => 1,
+    	'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'unregister_transcoders' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Connections Section
+     */
+    'relations' => array(
+        'bx_timeline',
+        'bx_notifications',
+    ),
+);
+
+/** @} */

+ 50 - 0
modules/boonex/groups/updates/13.0.2_13.0.3/source/js/invite_popup.js

@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Groups Groups
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxGroupsInvitePopup(oOptions) {
+	this._sActionsUrl = oOptions.sActionUrl;
+	this._sPopupId = oOptions.sPopupId == undefined ? {} : oOptions.sPopupId;
+	this._sKey = oOptions.sKey == undefined ? {} : oOptions.sKey;
+	this._sAcceptUrl = oOptions.sAcceptUrl == undefined ? {} : oOptions.sAcceptUrl;
+	this._sDeclineUrl = oOptions.sDeclineUrl == undefined ? {} : oOptions.sDeclineUrl;
+	this._iGroupProfileId = oOptions.iGroupProfileId == undefined ? {} : oOptions.iGroupProfileId;
+
+	var $this = this;
+	$(document).ready(function () {
+	    $this.init();
+	});
+}
+
+BxGroupsInvitePopup.prototype.init = function () {
+    var $this = this;
+    $('#' + $this._sPopupId + ' .bx-invite-accept').click(function () {
+        $this.onClickAccept();
+    });
+    $('#' + $this._sPopupId + ' .bx-invite-decline').click(function () {
+        $this.onClickDecline();
+    });
+
+    $('#' + $this._sPopupId).dolPopup();
+};
+
+BxGroupsInvitePopup.prototype.onClickAccept = function () {
+	var $this = this;
+	$.post($this._sActionsUrl + 'ProcessInvite/' + $this._sKey + '/' + $this._iGroupProfileId + '/1/', function () {
+	    location.href = $this._sAcceptUrl
+	});
+
+};
+
+BxGroupsInvitePopup.prototype.onClickDecline = function () {
+    var $this = this;
+    $.post($this._sActionsUrl + 'ProcessInvite/' + $this._sKey + '/' + $this._iGroupProfileId + '/0/', function () {
+        location.href = $this._sDeclineUrl
+    });
+};

+ 51 - 0
modules/boonex/invites/updates/13.0.1_13.0.2/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Invitations',
+    'version_from' => '13.0.1',
+    'version_to' => '13.0.2',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/invites/updates/update_13.0.1_13.0.2/',
+    'home_uri' => 'invites_update_1301_1302',
+
+    'module_dir' => 'boonex/invites/',
+    'module_uri' => 'invites',
+
+    'db_prefix' => 'bx_inv_',
+    'class_prefix' => 'BxInv',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Invitations',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/invites/updates/13.0.1_13.0.2/install/installer.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxInvUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 317 - 0
modules/boonex/invites/updates/13.0.1_13.0.2/source/classes/BxInvGridRequests.php

@@ -0,0 +1,317 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+define('BX_INV_FILTER_STATUS_NEW', 0);
+define('BX_INV_FILTER_STATUS_INVITED', 1);
+define('BX_INV_FILTER_STATUS_SEEN', 2);
+define('BX_INV_FILTER_STATUS_JOINED', 3);
+
+class BxInvGridRequests extends BxTemplGrid
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_sFilter1Name;
+    protected $_sFilter1Value;
+    protected $_aFilter1Values;
+    protected $_sParamsDivider;
+    
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_aQueryReset = array('order_field', 'order_dir', $this->_aOptions['paginate_get_start'], $this->_aOptions['paginate_get_per_page']);
+        
+        $this->_sModule = 'bx_invites';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+        
+        $this->_sFilter1Name = 'filter1';
+        $this->_aFilter1Values = array(
+            '' => _t('_bx_invites_request_status_for_filter_all'),
+            BX_INV_FILTER_STATUS_NEW => _t('_bx_invites_request_status_for_filter_new'),
+            BX_INV_FILTER_STATUS_INVITED => _t('_bx_invites_request_status_for_filter_invited'),
+            BX_INV_FILTER_STATUS_SEEN => _t('_bx_invites_request_status_for_filter_seen'),
+            BX_INV_FILTER_STATUS_JOINED => _t('_bx_invites_request_status_for_filter_joined')
+        );
+        
+        $sFilter1 = bx_get($this->_sFilter1Name);
+        if(!empty($sFilter1)) {
+            $this->_sFilter1Value = bx_process_input($sFilter1);
+            $this->_aQueryAppend['filter1'] = $this->_sFilter1Value;
+        }
+        $this->_sParamsDivider = '#-#';
+    }
+    
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        $sTableRequests = $CNF['TABLE_REQUESTS'];
+        
+        if(strpos($sFilter, $this->_sParamsDivider) !== false)
+            list($this->_sFilter1Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
+       
+        $sFilterSql = "";
+        if(isset($this->_sFilter1Value) && $this->_sFilter1Value != ''){
+            if ($this->_sFilter1Value == BX_INV_FILTER_STATUS_INVITED){
+                $sFilterSql = " AND " . $sTableRequests . ".`status` IN (" . BX_INV_FILTER_STATUS_INVITED . ', ' . BX_INV_FILTER_STATUS_SEEN . ', ' . BX_INV_FILTER_STATUS_JOINED . ')';
+            }
+            else{
+                $sFilterSql = " AND " . $sTableRequests . ".`status` = " . $this->_sFilter1Value;
+            }
+        }
+        $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString($sFilterSql);
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+    
+    protected function _getDataSqlOrderClause ($sOrderByFilter, $sOrderField, $sOrderDir, $bFieldsOnly = false)
+    {
+        return " ORDER BY `status` ASC, `date` DESC";
+    }
+    
+    public function performActionAdd()
+    {
+        $sAction = 'add';
+        $oForm = $this->_oModule->getFormObjectInvite();
+        if (!$oForm)
+            return '';
+
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?' . bx_encode_url_params($_GET, array('ids', '_r'));
+        $oForm->initChecker();
+
+        if($oForm->isSubmittedAndValid()) {
+            $sResult = $this->_oModule->processFormObjectInvite($oForm);
+            $aRes = array('msg' => $sResult);
+            echoJson($aRes);
+        }
+        else {
+            $sContent = BxTemplFunctions::getInstance()->popupBox('_bx_invites_form_invite', _t('_bx_invites_form_invite'), $this->_oModule->_oTemplate->parseHtmlByName('popup_invite.html', array(
+                'form_id' => $oForm->id,
+                'form' => $oForm->getCode(true),
+                'object' => $this->_sObject,
+                'action' => $sAction
+            )));
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => true))));
+        }
+    }
+    
+    public function performActionInfo()
+    {
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $aRequest = $this->_oModule->_oDb->getRequests(array('type' => 'by_id', 'value' => (int)array_shift($aIds)));
+        if(empty($aRequest) || !is_array($aRequest)){
+            echoJson(array());
+            exit;
+        }
+
+        $sContent = BxTemplFunctions::getInstance()->transBox('bx-invites-info-popup', $this->_oModule->_oTemplate->getBlockRequestText($aRequest));
+
+        echoJson(array('popup' => array('html' => $sContent)));
+    }
+    
+    public function performActionInviteInfo()
+    {
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $aRequest = $this->_oModule->_oDb->getInvites(array('type' => 'all', 'value' => (int)array_shift($aIds)));
+        if(empty($aRequest) || !is_array($aRequest)){
+            echoJson(array());
+            exit;
+        }
+
+        $sContent = BxTemplFunctions::getInstance()->transBox('bx-invites-info-popup', $this->_oModule->_oTemplate->getBlockInviteInfo($aRequest));
+
+        echoJson(array('popup' => array('html' => $sContent)));
+    }
+    
+    public function performActionInvite($aParams = array())
+    {
+        $iProfileId = $this->_oModule->getProfileId();
+
+        $mixedAllowed = $this->_oModule->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true) {
+            echoJson(array('msg' => $mixedAllowed));
+            exit;
+        }
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $sText = _t('_bx_invites_msg_invitation');
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+            $aRequest = $this->_oModule->_oDb->getRequests(array('type' => 'by_id', 'value' => $iId));
+            if(empty($aRequest) || !is_array($aRequest))
+                continue;
+            
+            $mixedResult = $this->_oModule->invite(BX_INV_TYPE_FROM_SYSTEM, $aRequest['email'], $sText);
+            if(empty($mixedResult) || !is_array($mixedResult))
+                continue;
+
+            $this->_oModule->_oDb->attachInviteToRequest($iId, (int)array_shift($mixedResult));
+
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected, 'msg' => _t('_bx_invites_msg_invitation_sent', $iAffected)) : array('msg' => _t('_bx_invites_err_invite')));
+    }
+    
+    public function performActionDelete($aParams = array())
+    {
+        $iProfileId = $this->_oModule->getProfileId();
+
+        $mixedAllowed = $this->_oModule->isAllowedDeleteRequest($iProfileId);
+        if($mixedAllowed !== true) {
+            echoJson(array('msg' => $mixedAllowed));
+            exit;
+        }
+
+        $iAffected = 0;
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            exit;
+        }
+
+        $oForm = BxDolForm::getObjectInstance($this->_oModule->_oConfig->getObject('form_request'), $this->_oModule->_oConfig->getObject('form_display_request_send'));
+
+        $aIdsAffected = array ();
+        foreach($aIds as $iId) {
+            if(!$oForm->delete($iId))
+                continue;
+
+            $this->_oModule->isAllowedDeleteRequest($iProfileId, true);
+
+            $aIdsAffected[] = $iId;
+            $iAffected++;
+        }
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_bx_invites_err_delete_request')));
+    }
+    
+    protected function _getFilterControls ()
+    {
+        parent::_getFilterControls();
+        return  $this->_getFilterSelectOne($this->_sFilter1Name, $this->_sFilter1Value, $this->_aFilter1Values) . $this->_getSearchInput();
+    }
+    
+    protected function _getSearchInput()
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+        $aInputSearch = array(
+            'type' => 'text',
+            'name' => 'search',
+            'attrs' => array(
+                'id' => 'bx-grid-search-' . $this->_sObject,
+                'onKeyup' => 'javascript:$(this).off(\'keyup focusout\'); ' . $sJsObject . '.onChangeFilter(this)',
+                'onBlur' => 'javascript:' . $sJsObject . '.onChangeFilter(this)',
+            )
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputSearch);
+    }
+    
+    protected function _getFilterSelectOne($sFilterName, $sFilterValue, $aFilterValues)
+    {
+        if(empty($sFilterName) || empty($aFilterValues))
+            return '';
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+
+        foreach($aFilterValues as $sKey => $sValue)
+            $aFilterValues[$sKey] = _t($sValue);
+
+        $aInputModules = array(
+            'type' => 'select',
+            'name' => $sFilterName,
+            'attrs' => array(
+                'id' => 'bx-grid-' . $sFilterName . '-' . $this->_sObject,
+                'onChange' => 'javascript:' . $sJsObject . '.onChangeFilter(this)'
+            ),
+            'value' => $sFilterValue,
+            'values' => $aFilterValues
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputModules);
+    }
+
+    protected function _getCellNip($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(long2ip($mixedValue), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellDate($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellStatus($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sStatus = _t('_bx_invites_request_status_new');
+        switch ($mixedValue) {
+            case 1:
+            case 2:
+                $sLinkHtml = $this->_oTemplate->parseLink('javascript:void(0)', $this->_oModule->_oDb->getInvites(array('type' => 'count_by_request', 'value' => $aRow['id'])), array(
+                    'title' => _t('_bx_invites_grid_action_title_adm_invite_info'),
+                    'bx_grid_action_single' => 'invite_info',
+                    'bx_grid_action_data' => $aRow['id']
+                ));
+                $sStatus = ($mixedValue == 1 ? _t('_bx_invites_request_status_invited') : _t('_bx_invites_request_status_seen')) . ' (' . $sLinkHtml . ')';
+                break;
+            case 3:
+                $sStatus = _t('_bx_invites_request_status_joined') . ' (' . bx_time_js($this->_oModule->_oDb->getInvites(array('type' => 'date_joined_by_request', 'value' => $aRow['id']))) . ')';
+                break;
+        }
+        return parent::_getCellDefault($sStatus, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellJoinedAccount($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sAccountInfo = "";
+        if(isset($aRow["status"]) && $aRow["status"] == 3){
+            $sAccountInfo = $this->_oModule->_oTemplate->getProfilesByAccount($this->_oModule->_oDb->getInvites(array('type' => 'account_by_request', 'value' => $aRow['id'])));
+        }
+        return parent::_getCellDefault($sAccountInfo, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getActionInvite($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        if(isset($aRow["status"]) && $aRow["status"] == 3)
+            return '';
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+    
+    protected function _getActionInviteInfo ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+    
+}
+
+/** @} */

+ 566 - 0
modules/boonex/invites/updates/13.0.1_13.0.2/source/classes/BxInvModule.php

@@ -0,0 +1,566 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAcl');
+
+define('BX_INV_TYPE_FROM_MEMBER', 'from_member');
+define('BX_INV_TYPE_FROM_SYSTEM', 'from_system');
+
+class BxInvModule extends BxDolModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_oConfig->init($this->_oDb);
+    }
+
+    /**
+     * ACTION METHODS
+     */
+    function actionGetLink()
+    {
+        $iProfileId = $this->getProfileId();
+        $iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return echoJson(array('message' => $mixedAllowed));
+
+        if(!isAdmin($iAccountId)) {
+            if($this->_oConfig->getCountPerUser() <= 0)
+                return echoJson(array('message' => _t('_bx_invites_err_limit_reached')));
+        }
+
+        $oKeys = BxDolKey::getInstance();
+        if(!$oKeys)
+            return  echoJson(array('message' => _t('_bx_invites_err_not_available')));
+
+        $sKey = $oKeys->getNewKey(false, $this->_oConfig->getKeyLifetime());
+
+        $oForm = $this->getFormObjectInvite();
+        $oForm->insert(array(
+            'account_id' => $iAccountId,
+            'profile_id' => $iProfileId,
+            'key' => $sKey,
+            'email' => '',
+            'date' => time()
+        ));
+        $this->onInvite($iProfileId);
+
+        echoJson(array('popup' => $this->_oTemplate->getLinkPopup(
+            $this->getJoinLink($sKey)
+        )));
+    }
+    
+    public function actionSetSeenMark($Code)
+    {
+        header('Content-Type: image/png');
+        if (isset($Code) && trim($Code) != "")
+            $this->_oDb->updateDateSeenForInvite($Code);
+    }
+
+    /**
+     * SERVICE METHODS
+     */
+    
+    public function serviceGetSafeServices()
+    {
+        return array (
+            'GetBlockInvite' => '',
+            'GetBlockFormInvite' => '',
+            'GetBlockFormRequest' => '',
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-other Other
+     * @subsubsection bx_invites-get_include get_include
+     * 
+     * @code bx_srv('bx_invites', 'get_include', [...]); @endcode
+     * 
+     * Get all necessary CSS and JS files to include in a page.
+     *
+     * @return string with all necessary CSS and JS files.
+     * 
+     * @see BxInvModule::serviceGetInclude
+     */
+    /** 
+     * @ref bx_invites-get_include "get_include"
+     */
+    public function serviceGetInclude()
+    {
+        return $this->_oTemplate->getInclude();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_invite get_block_invite
+     * 
+     * @code bx_srv('bx_invites', 'get_block_invite', [...]); @endcode
+     * 
+     * Get page block for member's Dashboard which displays invitations related info and action(s).
+     *
+     * @return an array describing a block to display on the site or empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockInvite
+     */
+    /** 
+     * @ref bx_invites-get_block_invite "get_block_invite"
+     */
+    public function serviceGetBlockInvite()
+    {
+        $iProfileId = $this->getProfileId();
+        $iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return '';
+
+        if(!isAdmin($iAccountId) && $this->_oConfig->getCountPerUser() <= 0)
+            return '';
+
+        return array(
+            'content' => $this->_oTemplate->getBlockInvite($iAccountId, $iProfileId)
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_form_invite get_block_form_invite
+     * 
+     * @code bx_srv('bx_invites', 'get_block_form_invite', [...]); @endcode
+     * 
+     * Get page block with invite form.
+     *
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockFormInvite
+     */
+    /** 
+     * @ref bx_invites-get_block_form_invite "get_block_form_invite"
+     */
+    public function serviceGetBlockFormInvite()
+    {
+        $oForm = $this->getFormObjectInvite();
+        $oForm->aInputs['text']['value'] = _t('_bx_invites_msg_invitation');
+
+        $sResult = '';
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            
+            $sResult = $this->processFormObjectInvite($oForm);
+            $sResult = MsgBox($sResult);
+        }
+
+        return array(
+            'content' => $sResult . $oForm->getCode()
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_form_request get_block_form_request
+     * 
+     * @code bx_srv('bx_invites', 'get_block_form_request', [...]); @endcode
+     * 
+     * Get page block with request invitation form.
+     *
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockFormRequest
+     */
+    /** 
+     * @ref bx_invites-get_block_form_request "get_block_form_request"
+     */
+    public function serviceGetBlockFormRequest()
+    {
+        $mixedResult = $this->_oTemplate->getBlockFormRequest();
+        if(is_array($mixedResult)) {
+            echoJson($mixedResult);
+            exit;
+        }
+
+        return array(
+            'content' => $mixedResult
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_manage_requests get_block_manage_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_block_manage_requests', [...]); @endcode
+     * 
+     * Get page block with manage invitation requests table.
+     *
+     * @return HTML string with block content to display on the site or empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockManageRequests
+     */
+    /** 
+     * @ref bx_invites-get_block_manage_requests "get_block_manage_requests"
+     */
+    public function serviceGetBlockManageRequests()
+    {
+        return $this->getBlockManage('requests');
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_manage_invites get_block_manage_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_block_manage_invites', [...]); @endcode
+     * 
+     * Get page block with manage invitations table.
+     *
+     * @return HTML string with block content to display on the site or empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockManageInvites
+     */
+    /** 
+     * @ref bx_invites-get_block_manage_invites "get_block_manage_invites"
+     */
+    public function serviceGetBlockManageInvites()
+    {
+        return $this->getBlockManage('invites');
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-other Other
+     * @subsubsection bx_invites-get_menu_addon_requests get_menu_addon_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_menu_addon_requests', [...]); @endcode
+     * 
+     * Get number or invitation requests.
+     *
+     * @return integer value with number of invitation requests.
+     * 
+     * @see BxInvModule::serviceGetMenuAddonRequests
+     */
+    /** 
+     * @ref bx_invites-get_menu_addon_requests "get_menu_addon_requests"
+     */
+    public function serviceGetMenuAddonRequests()
+    {
+        return array('counter3_value' => $this->_oDb->getRequests(array('type' => 'count_all')));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-other Other
+     * @subsubsection bx_invites-account_add_form_check account_add_form_check
+     * 
+     * @code bx_srv('bx_invites', 'account_add_form_check', [...]); @endcode
+     * 
+     * Perform neccessary checking on join form.
+     *
+     * @return empty string - if join is allowed and should be processed as usual, non-empty string - if join form need to be replaced with this code.
+     * 
+     * @see BxInvModule::serviceAccountAddFormCheck
+     */
+    /** 
+     * @ref bx_invites-account_add_form_check "account_add_form_check"
+     */
+    public function serviceAccountAddFormCheck()
+    {
+        $sReturn = '';
+
+        $oSession = BxDolSession::getInstance();
+        $sKeyCode = $this->_oConfig->getKeyCode();
+
+        $bKey = bx_get($sKeyCode) !== false;
+        if($bKey) {
+            $sKey = bx_process_input(bx_get($sKeyCode));
+
+            $oKeys = BxDolKey::getInstance();
+            if($oKeys && $oKeys->isKeyExists($sKey))
+                $oSession->setValue($sKeyCode, $sKey);
+        }
+
+        $sKey = $oSession->getValue($sKeyCode);
+        if($sKey !== false)
+            return $sReturn;
+
+        if($bKey)
+            $sReturn .= MsgBox(_t('_bx_invites_err_used'));
+        
+        if ($this->_oConfig->isRegistrationByInvitation())
+            $sReturn .= $this->_oTemplate->getBlockRequest();
+
+        return $sReturn;
+    }
+    
+    /**
+     * Data for Notifications module
+     */
+    public function serviceGetNotificationsData()
+    {
+    	$sModule = $this->_aModule['name'];
+
+    	$sEventPrivacy = $sModule . '_allow_view_event_to';
+		if(BxDolPrivacy::getObjectInstance($sEventPrivacy) === false)
+			$sEventPrivacy = '';
+
+        return array(
+            'handlers' => array(
+                array('group' => $sModule . '_object', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'request_notify', 'module_name' => $sModule, 'module_method' => 'get_notifications_request', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            ),
+            'settings' => array(
+                array('group' => 'request', 'unit' => $sModule, 'action' => 'request_notify', 'types' => array('personal')),
+            ),
+            'alerts' => array(
+                array('unit' => $sModule, 'action' => 'request_notify'),
+            )
+        );
+    }
+    
+    /**
+     * Entry post for Notifications module
+     */
+    public function serviceGetNotificationsRequest($aEvent)
+    {  
+        if (getParam('bx_invites_requests_notifications') != 'on')
+             return array();
+        
+        $aRequest = $this->_oDb->getRequests(array('type' => 'by_id', 'value' => $aEvent['object_id']));
+        if (!$aRequest)
+            return array();
+           
+        $CNF = &$this->_oConfig->CNF;
+        $sEntryUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($CNF['URL_REQUESTS']);
+            
+		return array(
+			'entry_sample' => $aRequest['name'] . '(' . $aRequest['email'] . ')',
+			'entry_url' => $sEntryUrl,
+			'entry_caption' => $aRequest['text'],
+			'entry_author' => '',
+			'entry_privacy' => '', //may be empty or not specified. In this case Public privacy will be used.
+			'lang_key' => '_bx_invites_alert_action_request', //may be empty or not specified. In this case the default one from Notification module will be used.
+		);
+    }
+    
+    
+    public function attachAccountIdToInvite($iAccountId, $sKey)
+    {
+        $this->_oDb->attachAccountIdToInvite($iAccountId, $sKey);
+    }
+    
+    public function invite($sType, $sEmails, $sText, $mixedLimit = false, $oForm = null)
+    {
+        $iProfileId = $this->getProfileId();
+        $iAccountId = $this->getAccountId($iProfileId);
+
+        $oKeys = BxDolKey::getInstance();
+        if(!$oKeys || !in_array($sType, array(BX_INV_TYPE_FROM_MEMBER, BX_INV_TYPE_FROM_SYSTEM)))
+            return false;
+
+        $iKeyLifetime = $this->_oConfig->getKeyLifetime();
+
+        $sEmailTemplate = '';
+        switch($sType) {
+            case BX_INV_TYPE_FROM_MEMBER:
+                $sEmailTemplate = 'bx_invites_invite_form_message';
+                break;
+
+            case BX_INV_TYPE_FROM_SYSTEM:
+                $sEmailTemplate = 'bx_invites_invite_by_request_message';
+                break;
+        }
+
+        if(empty($oForm))
+            $oForm = $this->getFormObjectInvite();
+
+        $aMessage = BxDolEmailTemplates::getInstance()->parseTemplate($sEmailTemplate, array(
+            'text' => $sText
+        ), $iAccountId, $iProfileId);
+
+        $aAccountIds = array();
+        $iDate = time();
+        $aEmails = preg_split("/[\s\n,;]+/", $sEmails);
+        if(is_array($aEmails) && !empty($aEmails)){
+            foreach($aEmails as $sEmail) {
+                if($mixedLimit !== false && (int)$mixedLimit <= 0)
+                    break;
+
+                $sEmail = trim($sEmail);
+                if(empty($sEmail))
+                    continue;
+
+                $sKey = $oKeys->getNewKey(false, $iKeyLifetime);
+                if(sendMail($sEmail, $aMessage['Subject'], $aMessage['Body'], 0, array('join_url' => $this->getJoinLink($sKey), 'seen_image_url' => $this->getSeenImageUrl($sKey)), BX_EMAIL_SYSTEM)) {
+                    $iInviteId = (int)$this->_oDb->insertInvite($iAccountId, $iProfileId, $sKey, $sEmail, $iDate);
+                    array_push($aAccountIds, $iInviteId);
+                    
+                    $this->onInvite($iProfileId);
+                    
+                    if($mixedLimit !== false)
+                        $mixedLimit -= 1;
+                }
+            }
+        }
+        return $aAccountIds;
+    }
+    
+    public function processFormObjectInvite($oForm)
+    {
+        $iProfileId = $this->getProfileId();
+        $iAccountId = $this->getAccountId($iProfileId);
+
+        $mixedAllowed = $this->isAllowedInvite($iProfileId);
+        if($mixedAllowed !== true)
+            return $mixedAllowed;
+
+        $mixedInvites = false;
+        if(!isAdmin($iAccountId)) {
+            if( $this->_oConfig->getCountPerUser() <= 0)
+                return _t('_bx_invites_err_limit_reached');
+        }
+        
+        $sEmails = bx_process_input($oForm->getCleanValue('emails'));
+        $sText = bx_process_pass($oForm->getCleanValue('text'));
+
+        $mixedResult = $this->invite(BX_INV_TYPE_FROM_MEMBER, $sEmails, $sText, $mixedInvites, $oForm);
+        if($mixedResult !== false)
+            $sResult = _t('_bx_invites_msg_invitation_sent', count($mixedResult));
+        else
+            $sResult = _t('_bx_invites_err_not_available');
+        
+        return  $sResult;
+    }
+
+    public function isAllowedInvite($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'invite', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function isAllowedRequest($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'request', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function isAllowedDeleteRequest($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'delete request', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+    
+    public function isAllowedDeleteInvite($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'delete invite', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function getProfileId()
+    {
+        return isLogged() ? bx_get_logged_profile_id() : 0;
+    }
+
+    public function getProfileObject($iProfileId = 0)
+    {
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if (!$oProfile)
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+        return $oProfile;
+    }
+
+    public function getAccountId($iProfileId)
+    {
+        $oProfile = $this->getProfileObject($iProfileId);
+        if($oProfile->id() == 0)
+            return 0;
+
+        return $oProfile->getAccountId();
+    }
+
+    public function onRequest($iRequestId)
+    {
+        //--- Event -> Request for Alerts Engine ---//
+        bx_alert($this->_oConfig->getObject('alert'), 'request', $iRequestId);
+        $aProfiles = BxDolAclQuery::getInstance()->getProfilesByMembership(array(MEMBERSHIP_ID_MODERATOR, MEMBERSHIP_ID_ADMINISTRATOR));
+        foreach($aProfiles as $aProfile) {
+            bx_alert($this->_oConfig->getObject('alert'), 'request_notify', $iRequestId, 0, array('parent_author_id' => $aProfile['id']));
+        }
+        //--- Event -> Request for Alerts Engine ---//
+    }
+
+    public function getFormObjectInvite($sDisplay = '')
+    {
+        if(empty($sDisplay))
+            $sDisplay = $this->_oConfig->getObject('form_display_invite_send');
+
+        bx_import('FormCheckerHelper', $this->_aModule);
+        return BxDolForm::getObjectInstance($this->_oConfig->getObject('form_invite'), $sDisplay);
+    }
+    
+    protected function getBlockManage($sType)
+    {
+        $this->_oTemplate->addJs('jquery.form.min.js');
+        $this->_oTemplate->addJs('main.js');
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_' . $sType));
+        if(!$oGrid)
+            return '';
+
+        $this->_oTemplate->addCss(array('main.css'));
+        $this->_oTemplate->addJsTranslation(array('_sys_grid_search'));
+       
+        return array(
+           'menu' => $this->_oTemplate->getMenuForManageBlocks($sType),
+           'content' => $this->_oTemplate->getJsCode('main', array('grid' => $sType)) . $oGrid->getCode()
+       );
+    }
+
+    public function onInvite($iProfileId)
+    {
+        $this->isAllowedInvite($iProfileId, true);
+
+        //--- Event -> Invite for Alerts Engine ---//
+        bx_alert($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
+        //--- Event -> Invite for Alerts Engine ---//
+    }
+    
+    public function getJoinLink($sKey)
+    {
+        $sKeyCode = $this->_oConfig->getKeyCode();
+
+        $sJoinUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=create-account');
+        return bx_append_url_params($sJoinUrl, array($sKeyCode => $sKey));
+    }
+    
+    public function getSeenImageUrl($sKey)
+    {
+        return  BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'SetSeenMark/' . $sKey . "/";
+    }
+
+}
+
+/** @} */

+ 80 - 0
modules/boonex/invites/updates/13.0.1_13.0.2/source/install/config.php

@@ -0,0 +1,80 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Invites Invites
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_invites',
+    'title' => 'Invitations',
+    'note' => 'Invitations module.',
+    'version' => '13.0.2',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/invites/',
+    'home_uri' => 'invites',
+
+    'db_prefix' => 'bx_inv_',
+    'class_prefix' => 'BxInv',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Invitations',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+    
+    /**
+      * Relations Section
+      */
+    'relations' => array(
+    	'bx_notifications'
+    ),
+);
+
+/** @} */

+ 51 - 0
modules/boonex/lucid/updates/13.0.4_13.0.5/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Lucid',
+    'version_from' => '13.0.4',
+    'version_to' => '13.0.5',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '13.0.0-B3'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/lucid/updates/update_13.0.4_13.0.5/',
+    'home_uri' => 'lucid_update_1304_1305',
+
+    'module_dir' => 'boonex/lucid/',
+    'module_uri' => 'lucid',
+
+    'db_prefix' => 'bx_lucid_',
+    'class_prefix' => 'BxLucid',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Boonex Lucid Template',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 26 - 0
modules/boonex/lucid/updates/13.0.4_13.0.5/install/installer.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ */
+
+class BxLucidUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+
+    public function update($aParams)
+    {
+        $aResult = parent::update($aParams);
+        if(!$aResult['result'])
+            return $aResult;
+
+        $oCacheUtilities = BxDolCacheUtilities::getInstance();
+        $oCacheUtilities->clear('css');
+        $oCacheUtilities->clear('template');
+
+        return $aResult;
+    }
+}

+ 1343 - 0
modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/css/default.less

@@ -0,0 +1,1343 @@
+@import (reference) '../../../../../../../template/css/_mixins.less';
+
+.@{bx-root-class-name}.bx-def-font {
+    font-family:@bx-font-family;
+    font-weight:400; /* 26.13.13: prev val 300 */
+    .font-size(@bx-font-size-default);
+    color:@bx-font-color-default;
+}
+
+.@{bx-root-class-name}.bx-def-color-bg-page {
+    .background-color (@bx-color-page);
+}
+
+.@{bx-root-class-name}.bx-def-image-bg-page {
+    background-image: @bx-image-bg-page;
+    background-repeat: @bx-image-bg-page-repeat;
+    background-size: @bx-image-bg-page-size;
+    background-position: center center;
+}
+
+.@{bx-root-class-name} {
+    @import '../../../../../../../template/css/default.less';
+
+    /**
+     * Is used for inputs and buttons. They should have the same value 
+     * because Input and Button can be positioned in one line.
+     */
+    @base-input-box-sizing: border-box;
+
+
+    /* height */
+    .bx-header {
+        height: auto !important;
+    }
+
+    #bx-toolbar-content {
+        height: @bx-height-header !important;
+    }
+
+    .bx-toolbar-item .bx-menu-toolbar .bx-menu-toolbar-item a img:not(.bx-base-pofile-unit-thumb) {
+        max-width: @bx-height-header - 2;
+        max-height: @bx-height-header - 2;
+    }
+
+    .bx-main-content .bx-main-column.narrow .bx-menu-toolbar-padding,
+    .cd-main-content .content-wrapper {
+        padding-top: @bx-height-header;
+    }
+
+
+    /* content paddings */
+    .bx-content-padding-header {
+        padding: @bx-content-padding-header;
+    }
+    .bx-content-padding-footer {
+        padding: @bx-content-padding-footer;
+    }
+    .bx-content-padding-block {
+        padding: @bx-content-padding-block;
+    }
+
+
+    /* shadow */
+    .bx-shadow-header {
+        -webkit-box-shadow: @bx-shadow-header;
+        -moz-box-shadow: @bx-shadow-header;
+        box-shadow: @bx-shadow-header;
+    }
+    .bx-shadow-footer {
+        -webkit-box-shadow: @bx-shadow-footer;
+        -moz-box-shadow: @bx-shadow-footer;
+        box-shadow: @bx-shadow-footer;
+    }
+    .bx-shadow-block {
+        -webkit-box-shadow: @bx-shadow-block;
+        -moz-box-shadow: @bx-shadow-block;
+        box-shadow: @bx-shadow-block;
+    }
+    .bx-def-box {
+        -webkit-box-shadow: @bx-shadow-card;
+        -moz-box-shadow: @bx-shadow-card;
+        box-shadow: @bx-shadow-card;
+    }
+    .bx-popup-applied {
+        border-radius: @bx-border-radius-popup;
+        background-clip: padding-box;
+    }
+    .bx-popup-applied:not(.bx-popup-chain) .bx-popup,
+    .bx-popup-applied.bx-popup-chain .bx-popup-chain-item {
+        -webkit-box-shadow: @bx-shadow-popup;
+        -moz-box-shadow: @bx-shadow-popup;
+        box-shadow: @bx-shadow-popup;
+    }
+    .bx-popup-applied.bx-popup-chain .bx-popup-chain-item a:hover {
+        background-color: @bx-color-hl;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper {
+        -webkit-box-shadow: @bx-shadow-menu-slide;
+        -moz-box-shadow: @bx-shadow-menu-slide;
+        box-shadow: @bx-shadow-menu-slide;
+    }
+
+
+    /* background images */
+    .bx-def-image-bg-header,
+    .bx-def-image-bg-footer,
+    .bx-def-image-bg-block,
+    .bx-def-box,
+    .bx-popup-color-bg,
+    .bx-popup-wrapper.bx-popup-slide-wrapper,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main,
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main,
+    #bx-sliding-menu-account.bx-sliding-menu-main,
+    .bx-menu-main-bar-wrapper {
+        background-position: center center;
+    }
+    .bx-def-image-bg-header {
+        background-image: @bx-image-bg-header;
+        background-repeat: @bx-image-bg-header-repeat;
+        background-size: @bx-image-bg-header-size;
+    }
+    .bx-def-image-bg-footer {
+        background-image: @bx-image-bg-footer;
+        background-repeat: @bx-image-bg-footer-repeat;
+        background-size: @bx-image-bg-footer-size;
+    }
+    .bx-def-image-bg-block {
+        background-image: @bx-image-bg-block;
+        background-repeat: @bx-image-bg-block-repeat;
+        background-size: @bx-image-bg-block-size;
+    }
+    .bx-def-box {
+        background-image: @bx-image-bg-box;
+        background-repeat: @bx-image-bg-box-repeat;
+        background-attachment: @bx-image-bg-box-attachment;
+        background-size: @bx-image-bg-box-size;
+    }
+
+    /* body */
+    a {
+        color: @bx-color-link-body; 
+    }
+    a:hover {
+        color: @bx-color-link-body-hover; 
+    }
+    .sys-icon:not(.sys-colored):not(.bx-vote-star),
+    .sys-icon-a:not(.sys-colored):not(.bx-vote-star) {
+        color: @bx-color-icon-body; 
+    }
+    a:hover > .sys-icon:not(.sys-colored),
+    a:hover > .sys-icon-a:not(.sys-colored) {
+        color: @bx-color-icon-body-hover; 
+    }
+    .sys-icon-a i {
+        .background-color (@bx-color-icon-body) !important;
+        color: @bx-color-icon-body;
+    }
+    a:hover > .sys-icon-a i {
+        .background-color (@bx-color-icon-body-hover) !important;
+        color: @bx-color-icon-body-hover;
+    }
+
+    /* header */
+    .bx-header.bx-def-color-bg-header {
+        .background-color (@bx-color-header);
+    }
+    .bx-header.bx-def-border-header {
+        border-bottom-width: @bx-border-width-header;
+        border-bottom-style: @bx-border-type;
+        border-bottom-color: @bx-color-border-header;
+    }
+    .bx-header a {
+        color: @bx-color-link-header; 
+    }
+    .bx-header a:hover {
+        color: @bx-color-link-header-hover;
+    }
+    .bx-header .sys-icon:not(.sys-colored),
+    .bx-header .sys-icon-a:not(.sys-colored),
+    .cd-dropdown .cd-dropdown-content a .sys-icon:not(.sys-colored),
+    .cd-dropdown .cd-dropdown-content a .sys-icon-a:not(.sys-colored) {
+        color: @bx-color-icon-header; 
+    }
+    .bx-header .cd-nav-trigger span, 
+    .bx-header .cd-nav-trigger span::before, 
+    .bx-header .cd-nav-trigger span::after,
+    .bx-header .cd-nav-trigger.nav-is-visible span::before, 
+    .bx-header .cd-nav-trigger.nav-is-visible span::after {
+        background: @bx-color-icon-header;
+    }
+    .bx-header a:hover .sys-icon,
+    .bx-header a:hover .sys-icon-a,
+    .bx-header li.bx-menu-tab-active a .sys-icon,
+    .bx-header li.bx-menu-tab-active a .sys-icon-a {
+        color: @bx-color-icon-header-hover; 
+    }
+    .bx-header .cd-nav-trigger.nav-is-visible:hover span {
+        background: rgba(255, 255, 255, 0);
+    }
+    .bx-header .cd-nav-trigger:hover span, 
+    .bx-header .cd-nav-trigger:hover span::before, 
+    .bx-header .cd-nav-trigger:hover span::after,
+    .bx-header .cd-nav-trigger.nav-is-visible:hover span::before, 
+    .bx-header .cd-nav-trigger.nav-is-visible:hover span::after {
+        background: @bx-color-icon-header-hover;
+    }
+    .bx-header .sys-icon-a:not(.sys-colored) i {
+        .background-color (@bx-color-icon-header) !important;
+        color: @bx-color-icon-header;
+    }
+    .bx-header a:hover .sys-icon-a i {
+        .background-color (@bx-color-icon-header-hover) !important;
+        color: @bx-color-icon-header-hover;
+    }
+
+    /* footer */
+    .bx-footer-wrapper.bx-def-color-bg-footer {
+        .background-color (@bx-color-footer);    
+    }
+    .bx-footer-wrapper.bx-def-border-footer {
+        border-top-width: @bx-border-width-footer;
+        border-top-style: @bx-border-type;
+        border-top-color: @bx-color-border-footer;
+    }
+
+    .bx-footer {
+        color: @bx-font-color-footer;
+    }
+    .bx-footer a {
+        color: @bx-color-link-footer; 
+    }
+    .bx-footer a:hover {
+        color: @bx-color-link-footer-hover; 
+    }
+    .bx-footer .sys-icon,
+    .bx-footer .sys-icon-a {
+        color: @bx-color-icon-footer; 
+    }
+    .bx-footer a:hover .sys-icon,
+    .bx-footer a:hover .sys-icon-a {
+        color: @bx-color-icon-footer-hover; 
+    }
+    .bx-footer .sys-icon-a i {
+        .background-color (@bx-color-icon-footer) !important;
+        color: @bx-color-icon-footer;
+    }
+    .bx-footer a:hover .sys-icon-a i {
+        .background-color (@bx-color-icon-footer-hover) !important;
+        color: @bx-color-icon-footer-hover;
+    }
+
+    /* fonts */
+    .bx-def-font-inputs {
+        font-family: @bx-font-family-form-input;
+        font-size: @bx-font-size-form-input;
+        color: @bx-font-color-form-input;
+    }
+
+    h1,
+    .bx-def-font-h1 {
+        font-weight: @bx-font-weight-h1;
+        color: @bx-font-color-default-h1;
+    }
+    h1.bx-def-font-grayed,
+    h1 .bx-def-font-grayed,
+    .bx-def-font-h1.bx-def-font-grayed,
+    .bx-def-font-h1 .bx-def-font-grayed {
+        color: @bx-font-color-grayed-h1;
+    }
+    h1.bx-def-font-contrasted,
+    h1.bx-def-font-contrasted:after,
+    h1.bx-def-font-contrasted:before,
+    h1 .bx-def-font-contrasted,
+    h1 .bx-def-font-contrasted:after,
+    h1 .bx-def-font-contrasted:before,
+    .bx-def-font-h1.bx-def-font-contrasted,
+    .bx-def-font-h1.bx-def-font-contrasted:after,
+    .bx-def-font-h1.bx-def-font-contrasted:before,
+    .bx-def-font-h1 .bx-def-font-contrasted,
+    .bx-def-font-h1 .bx-def-font-contrasted:after,
+    .bx-def-font-h1 .bx-def-font-contrasted:before {
+        color: @bx-font-color-contrasted-h1;
+    }
+    h1 a,
+    .bx-def-font-h1 a,
+    a.bx-def-font-h1 {
+        color: @bx-font-color-link-h1;
+    }
+    h1 a:hover,
+    .bx-def-font-h1 a:hover,
+    a.bx-def-font-h1:hover {
+        color: @bx-font-color-link-h1-hover;
+    }
+
+    h2,
+    .bx-def-font-h2 {
+        font-weight: @bx-font-weight-h2;
+        color: @bx-font-color-default-h2;
+    }
+    h2.bx-def-font-grayed,
+    h2 .bx-def-font-grayed,
+    .bx-def-font-h2.bx-def-font-grayed,
+    .bx-def-font-h2 .bx-def-font-grayed {
+        color: @bx-font-color-grayed-h2;
+    }
+    h2.bx-def-font-contrasted,
+    h2.bx-def-font-contrasted:after,
+    h2.bx-def-font-contrasted:before,
+    h2 .bx-def-font-contrasted,
+    h2 .bx-def-font-contrasted:after,
+    h2 .bx-def-font-contrasted:before,
+    .bx-def-font-h2.bx-def-font-contrasted,
+    .bx-def-font-h2.bx-def-font-contrasted:after,
+    .bx-def-font-h2.bx-def-font-contrasted:before,
+    .bx-def-font-h2 .bx-def-font-contrasted,
+    .bx-def-font-h2 .bx-def-font-contrasted:after,
+    .bx-def-font-h2 .bx-def-font-contrasted:before {
+        color: @bx-font-color-contrasted-h2;
+    }
+    h2 a,
+    .bx-def-font-h2 a,
+    a.bx-def-font-h2 {
+        color: @bx-font-color-link-h2;
+    }
+    h2 a:hover,
+    .bx-def-font-h2 a:hover,
+    a.bx-def-font-h2:hover {
+        color: @bx-font-color-link-h2-hover;
+    }
+
+    h3,
+    .bx-def-font-h3 {
+        font-weight: @bx-font-weight-h3;
+        color: @bx-font-color-default-h3;
+    }
+    h3.bx-def-font-grayed,
+    h3 .bx-def-font-grayed,
+    .bx-def-font-h3.bx-def-font-grayed,
+    .bx-def-font-h3 .bx-def-font-grayed {
+        color: @bx-font-color-grayed-h3;
+    }
+    h3.bx-def-font-contrasted,
+    h3.bx-def-font-contrasted:after,
+    h3.bx-def-font-contrasted:before,
+    h3 .bx-def-font-contrasted,
+    h3 .bx-def-font-contrasted:after,
+    h3 .bx-def-font-contrasted:before,
+    .bx-def-font-h3.bx-def-font-contrasted,
+    .bx-def-font-h3.bx-def-font-contrasted:after,
+    .bx-def-font-h3.bx-def-font-contrasted:before,
+    .bx-def-font-h3 .bx-def-font-contrasted,
+    .bx-def-font-h3 .bx-def-font-contrasted:after,
+    .bx-def-font-h3 .bx-def-font-contrasted:before {
+        color: @bx-font-color-contrasted-h3;
+    }
+    h3 a,
+    .bx-def-font-h3 a,
+    a.bx-def-font-h3 {
+        color: @bx-font-color-link-h3;
+    }
+    h3 a:hover,
+    .bx-def-font-h3 a:hover,
+    a.bx-def-font-h3:hover {
+        color: @bx-font-color-link-h3-hover;
+    }
+
+    /* cover */
+    .bx-menu-toolbar-padding .bx-def-cover-color-bg {
+        background-color: @bx-color-cover;
+    }
+
+    .bx-menu-toolbar-padding .bx-cover-wrapper,
+    .bx-menu-toolbar-padding .bx-base-pofile-cover {
+        border-width: @bx-border-width-cover;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-cover;
+
+        border-radius: @bx-border-radius-cover;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-cover;
+        -moz-box-shadow: @bx-shadow-cover;
+        box-shadow: @bx-shadow-cover;
+    }
+    .bx-cover-wrapper .bx-cover {
+        min-height: @bx-height-cover;
+    }
+    .bx-cover-wrapper .bx-cover,
+    .bx-cover-wrapper .bx-cover .bx-cover-actions .bx-menu-btns-hor {
+        text-align: @bx-text-align-cover;
+    }
+    .bx-cover-wrapper .bx-cover.bx-def-padding {
+        padding: @bx-content-padding-cover;
+    }
+    .bx-cover-wrapper .bx-cover .bx-cover-image img {
+        border-width: @bx-border-width-cover-icon;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-cover-icon;
+
+        border-radius: @bx-border-radius-cover-icon;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-cover-icon;
+        -moz-box-shadow: @bx-shadow-cover-icon;
+        box-shadow: @bx-shadow-cover-icon;
+    }
+
+    .bx-cover-wrapper .bx-cover .bx-cover-title {
+        text-shadow: @bx-shadow-text-cover;
+
+        font-family: @bx-font-family-cover;
+    }
+    .bx-cover-wrapper .bx-cover .bx-cover-title,
+    .bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted,
+    .bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted:after,
+    .bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted:before {
+        color: @bx-color-font-cover;
+    }
+    .bx-cover-wrapper .bx-cover .bx-cover-title,
+    .bx-cover-wrapper .bx-cover .bx-cover-title.bx-def-font-h1 {
+        font-size: @bx-font-size-cover;
+        font-weight: @bx-font-weight-cover;
+    }
+
+
+    /* block */
+    .bx-def-border-block {
+        border-width: @bx-border-width-block;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-block;
+
+        border-radius: @bx-border-radius-block;
+        background-clip: padding-box;
+    }
+    .bx-def-border-radius-block {
+        border-radius: @bx-border-radius-block;
+        background-clip: padding-box;
+    }
+    .bx-db-header {
+        padding: @bx-title-padding-block;
+
+        border-width: @bx-border-width-block-title;
+        border-style: solid;
+        border-color: @bx-color-border-block-title;
+
+        border-radius: @bx-border-radius-block-title;
+    }
+    .bx-def-color-bg-block .bx-db-header,
+    .bx-def-image-bg-block .bx-db-header {
+        background-color: @bx-color-block-title;
+    }
+    .bx-db-header .bx-db-title {
+        line-height: 1.2;
+        font-family: @bx-font-family-block-title;
+        font-size: @bx-font-size-block-title;
+        font-weight: @bx-font-weight-block-title;
+        color: @bx-color-font-block-title;
+    }
+    .bx-db-divider {
+        border-top:@bx-height-block-title-div @bx-border-type @bx-color-block-title-div;
+    }
+
+
+    /* box */
+    .bx-def-box {
+        border-width: @bx-border-width-box;
+        border-style: @bx-border-type;
+        border-color: @bx-color-border-box;
+    }
+    .bx-def-box.bx-def-padding {
+        padding: @bx-content-padding-card;
+    }
+    .bx-def-box.bx-def-color-bg-box {
+        .background-color (@bx-color-box);
+    }
+    .bx-def-color-bg-box-active,
+    .bx-def-color-bg-box-hover:hover {
+        .background-color (@bx-color-box-hover);
+    }
+    .bx-def-box-round-corners,
+    .bx-def-box.bx-def-round-corners {
+        border-radius: @bx-border-radius-box;
+        background-clip: padding-box;
+    }
+    .bx-def-box-round-corners-int {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+        background-clip: padding-box;
+    }
+    .bx-def-box-round-corners-int-top {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+        background-clip: padding-box;
+    }
+    .bx-def-box-round-corners-int-bottom {
+        border-radius: 0 0 @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+        background-clip: padding-box;
+    }
+    .bx-base-pofile-unit-with-cover .bx-def-round-corners .bx-base-pofile-unit-cover {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    }
+    .bx-base-text-unit.bx-base-text-unit-ext.bx-def-round-corners img.bx-base-text-unit-cover.bx-def-round-corners,
+    .bx-base-text-unit.bx-base-text-unit-ext .bx-def-round-corners img.bx-base-text-unit-cover.bx-def-round-corners {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    }
+    .bx-base-text-unit.bx-base-text-unit-gallery.bx-def-round-corners .bx-base-text-unit-thumb.bx-def-round-corners,
+    .bx-base-text-unit.bx-base-text-unit-gallery .bx-def-round-corners .bx-base-text-unit-thumb.bx-def-round-corners {
+        border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    }
+
+    /* box: timeline */
+    .bx-tl-view div.bx-tl-item div.bx-tl-item-footer {
+        border-radius: 0 0 @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+    }
+
+    /* popup */
+    .bx-popup-border {
+        border-width: @bx-border-width-popup;
+        border-style: solid;
+        border-color: @bx-color-border-popup;
+
+        border-radius: @bx-border-radius-popup;
+        background-clip: padding-box;
+    }
+    .bx-popup-color-bg {
+        background-color: @bx-color-popup;
+
+        background-image: @bx-image-bg-popup;
+        background-repeat: @bx-image-bg-popup-repeat;
+        background-size: @bx-image-bg-popup-size;
+    }
+    .bx-popup-content-indent {
+        padding: @bx-content-padding-popup;
+    }
+    .bx-popup-header {
+        padding: @bx-title-padding-popup;
+    }
+    .bx-popup-header .bx-popup-element-close {
+        margin: @bx-title-padding-popup;
+    }
+    .bx-popup-header-color-bg {
+        background-color: @bx-color-popup-title;
+    }
+    .bx-popup-header h2,
+    .bx-popup-header .bx-popup-element-close {
+        line-height: 1.8rem;
+    }
+    .bx-popup-header h2 {
+        font-family: @bx-font-family-popup-title;
+        font-size: @bx-font-size-popup-title;
+    }
+    .bx-popup-header h2,
+    .bx-popup-header.bx-def-font-contrasted h2,
+    .bx-popup-header .bx-popup-element-close,
+    .bx-popup-header.bx-def-font-contrasted .bx-popup-element-close,
+    .bx-popup-header .bx-popup-element-close .sys-icon,
+    .bx-popup-header.bx-def-font-contrasted .bx-popup-element-close .sys-icon {
+        color: @bx-color-font-popup-title;
+    }
+
+    /* slide menu */
+    .bx-popup-wrapper.bx-popup-slide-wrapper {
+        border-width: @bx-border-width-menu-slide;
+        border-style: solid;
+        border-color: @bx-color-border-menu-slide;
+
+        .background-color (@bx-color-menu-slide);
+
+        background-image: @bx-image-bg-menu-slide;
+        background-repeat: @bx-image-bg-menu-slide-repeat;
+        background-size: @bx-image-bg-menu-slide-size;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper.bx-def-padding {
+        padding: @bx-content-padding-menu-slide;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper li a {
+        text-shadow: @bx-shadow-font-menu-slide;
+
+        font-family: @bx-font-family-menu-slide;
+        font-size: @bx-font-size-menu-slide;
+        font-weight: @bx-font-weight-menu-slide;
+        color: @bx-font-color-menu-slide;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper li a:hover {
+        color: @bx-font-color-menu-slide-hover;
+    }
+    .bx-popup-wrapper.bx-popup-slide-wrapper li.bx-menu-tab-active a,
+    .bx-popup-wrapper.bx-popup-slide-wrapper li.bx-menu-inter-act {
+        color: @bx-font-color-menu-slide-active;
+    }
+
+    /* main menu */
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main ul.bx-menu-object-sys_site {
+        -webkit-justify-content: @bx-text-align-menu-main-items;
+        justify-content: @bx-text-align-menu-main-items;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt {
+        padding: @bx-content-padding-menu-main;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a {
+        text-shadow: @bx-shadow-font-menu-main;
+
+        font-family: @bx-font-family-menu-main;
+        font-size: @bx-font-size-menu-main;
+        font-weight: @bx-font-weight-menu-main;
+        color: @bx-font-color-menu-main;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .sys-icon,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .sys-icon-a {
+        color: @bx-font-color-menu-main-active;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover .sys-icon,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover .sys-icon-a {
+        color: @bx-font-color-menu-main-hover;
+    }
+
+
+    /* account menu */
+    #bx-sliding-menu-account.bx-sliding-menu-main,
+    #bx-sliding-menu-search.bx-sliding-menu-main,
+    #bx_notifications_preview.bx-sliding-menu,
+     {
+        -webkit-box-shadow: @bx-shadow-menu-account;
+        -moz-box-shadow: @bx-shadow-menu-account;
+        box-shadow: @bx-shadow-menu-account;
+
+        border-width: @bx-border-width-menu-account;
+        border-style: solid;
+        border-color: @bx-color-border-menu-account;
+
+        background-color: @bx-color-menu-account;
+
+        background-image: @bx-image-bg-menu-account;
+        background-repeat: @bx-image-bg-menu-account-repeat;
+        background-size: @bx-image-bg-menu-account-size;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt {
+        padding: @bx-content-padding-menu-account;
+    }
+    .bx-menu-ver.bx-menu-vertical-more-less li a,
+    .bx-menu-ver.bx-menu-vertical-more-less li a .sys-icon,
+    .bx-menu-ver.bx-menu-vertical-more-less li a .sys-icon-a,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .bx-def-font-h1,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .bx-def-font-h2,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt a:not(.bx-btn),
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .sys-icon {
+        color: @bx-font-color-menu-account;
+    }
+    .bx-menu-ver.bx-menu-vertical-more-less li a,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a:not(.bx-btn),
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a .bx-menu-floating-blocks-title {
+        text-shadow: @bx-shadow-font-menu-account;
+
+        font-family: @bx-font-family-menu-account;
+        font-size: @bx-font-size-menu-account;
+        font-weight: @bx-font-weight-menu-account;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li.bx-menu-tab-active a:not(.bx-btn) {
+        color: @bx-font-color-menu-account-active;
+    }
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a:not(.bx-btn):hover,
+    #bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a:not(.bx-btn):hover .sys-icon {
+        color: @bx-font-color-menu-account-hover;
+    }
+    .bx-menu-ver.bx-menu-vertical-more-less li a:hover,
+    .bx-menu-ver.bx-menu-vertical-more-less li a:hover .sys-icon,
+    .bx-menu-ver.bx-menu-vertical-more-less li a:hover .sys-icon-a {
+        color: @bx-font-color-menu-account-hover;
+    }
+
+
+    /* add menu */
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main {
+        -webkit-box-shadow: @bx-shadow-menu-add;
+        -moz-box-shadow: @bx-shadow-menu-add;
+        box-shadow: @bx-shadow-menu-add;
+
+        border-width: @bx-border-width-menu-add;
+        border-style: solid;
+        border-color: @bx-color-border-menu-add;
+
+        background-color: @bx-color-menu-add;
+
+        background-image: @bx-image-bg-menu-add;
+        background-repeat: @bx-image-bg-menu-add-repeat;
+        background-size: @bx-image-bg-menu-add-size;
+    }
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt {
+        padding: @bx-content-padding-menu-add;
+    }
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a {
+        text-shadow: @bx-shadow-font-menu-add;
+
+        font-family: @bx-font-family-menu-add;
+        font-size: @bx-font-size-menu-add;
+        font-weight: @bx-font-weight-menu-add;
+    }
+
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a,
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a .sys-icon {
+        color: @bx-font-color-menu-add;
+    }
+
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a,
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .sys-icon {
+        color: @bx-font-color-menu-add-active;
+    }
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a:hover,
+    #bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a:hover .sys-icon {
+        color: @bx-font-color-menu-add-hover;
+    }
+
+    /* page menu */
+    .bx-menu-main-bar-wrapper {
+        -webkit-box-shadow: @bx-shadow-menu-page;
+        -moz-box-shadow: @bx-shadow-menu-page;
+        box-shadow: @bx-shadow-menu-page;
+
+        border-width: @bx-border-width-menu-page;
+        border-style: solid;
+        border-color: @bx-color-border-menu-page;
+
+        background-color: @bx-color-menu-page;
+
+        background-image: @bx-image-bg-menu-page;
+        background-repeat: @bx-image-bg-menu-page-repeat;
+        background-size: @bx-image-bg-menu-page-size;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu {
+        padding: @bx-content-padding-menu-page;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu li a {
+        text-shadow: @bx-shadow-font-menu-page;
+
+        font-family: @bx-font-family-menu-page;
+        font-size: @bx-font-size-menu-page;
+        font-weight: @bx-font-weight-menu-page;
+        color: @bx-font-color-menu-page;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu li a:hover {
+        color: @bx-font-color-menu-page-hover;
+    }
+    .bx-menu-main-bar-wrapper .bx-menu-main-submenu li.bx-menu-tab-active a {
+        color: @bx-font-color-menu-page-active;
+    }
+
+    /* form */
+    .bx-form-value .bx-form-input-slider,
+    .bx-form-value .bx-form-input-doublerange,
+    .bx-form-value .bx-form-input-select_multiple,
+    .bx-form-value .bx-form-input-select,
+    .bx-form-value .bx-form-input-radio_set,
+    .bx-form-value .bx-form-input-checkbox_set,
+    .bx-form-value .bx-form-input-number,
+    .bx-form-value .bx-form-input-time,
+    .bx-form-value .bx-form-input-datepicker,
+    .bx-form-value .bx-form-input-datetime,
+    .bx-form-value .bx-form-input-wrapper-textarea.bx-form-input-wrapper-html,
+    .bx-form-value .bx-form-input-textarea,
+    .bx-form-value .bx-form-input-text,
+    .bx-form-value .bx-form-input-price,
+    .bx-form-value .bx-form-input-wrapper-price span,
+    .bx-form-value .bx-form-input-wrapper-password {
+        .box-sizing(@base-input-box-sizing);
+
+        border-color: @bx-color-border-form-input;
+        border-width: @bx-border-width-form-input;
+
+        border-radius: @bx-border-radius-form-input;
+        background-clip: padding-box;
+
+        background-color: @bx-color-form-input;
+
+        -webkit-box-shadow: @bx-shadow-form-input;
+        -moz-box-shadow: @bx-shadow-form-input;
+        box-shadow: @bx-shadow-form-input;
+    }
+    .bx-form-value .bx-form-input-slider,
+    .bx-form-value .bx-form-input-doublerange,
+    .bx-form-value .bx-form-input-select,
+    .bx-form-value .bx-form-input-number,
+    .bx-form-value .bx-form-input-time,
+    .bx-form-value .bx-form-input-datepicker,
+    .bx-form-value .bx-form-input-datetime,
+    .bx-form-value .bx-form-input-text,
+    .bx-form-value .bx-form-input-price,
+    .bx-form-value .bx-form-input-wrapper-price span,
+    .bx-form-value .bx-form-input-wrapper-password {
+        height: @bx-height-form-input;
+    }
+    .bx-form-value .bx-form-input-wrapper-textarea.bx-form-input-wrapper-html {
+        border-style: solid;
+    }
+    .bx-form-value .bx-form-input-textarea {
+        -webkit-box-shadow: none;
+        -moz-box-shadow: none;
+        box-shadow: none;
+    }
+    .bx-form-value .bx-form-input-textarea.bx-form-input-html 
+    {
+        border-width: 0;
+    }
+    .bx-form-value .bx-form-input-text.bx-form-input-autotoken:not(.bx-form-input-labels) {
+        height: @bx-height-form-input ;
+        line-height: @bx-height-form-input  - 0.5rem;
+        padding: 0.125rem;
+    }
+    
+    .bx-form-value .bx-form-input-text.bx-form-input-autotoken.bx-form-input-labels {
+        padding: 3px 0.125rem;
+    }
+    
+    .bx-form-value .bx-form-input-text.bx-form-input-autotoken .ui-autocomplete-input{
+        height: @bx-height-form-input  - 0.5rem;
+    }
+    
+    .bx-form-value .bx-form-input-text.bx-form-input-autotoken:not(.bx-form-input-labels) b .bx-def-thumb-size {
+        width: @bx-height-form-input;
+        height: @bx-height-form-input;
+        line-height: @bx-height-form-input;
+    }
+    .bx-form-value .bx-form-input-slider:focus,
+    .bx-form-value .bx-form-input-doublerange:focus,
+    .bx-form-value .bx-form-input-number:focus,
+    .bx-form-value .bx-form-input-time:focus,
+    .bx-form-value .bx-form-input-datepicker:focus,
+    .bx-form-value .bx-form-input-datetime:focus,
+    .bx-form-value .bx-form-input-textarea:focus,
+    .bx-form-value .bx-form-input-text:focus,
+    .bx-form-value .bx-form-input-price:focus,
+    .bx-form-value .bx-form-input-wrapper-password.bx-form-input-focus {
+        border-color: @bx-color-border-form-input-active;
+        background-color: @bx-color-form-input-active;
+    }
+    .bx-form-value .bx-switcher-cont.on > button {
+        background-color: @bx-color-form-input;
+    }
+
+
+    /* button (normal) */
+    .bx-btn {
+        .box-sizing(@base-input-box-sizing);
+        height: @bx-height-button;
+        line-height: (@bx-height-button - 0.125 * @bx-border-width-button);
+    
+        .background-color (@bx-color-button);
+
+        border-width: @bx-border-width-button;
+        border-style: solid;
+        border-color: @bx-color-border-button;
+
+        border-radius: @bx-border-radius-button;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-button;
+        -moz-box-shadow: @bx-shadow-button;
+        box-shadow: @bx-shadow-button;
+
+        text-shadow: @bx-shadow-font-button;
+        text-transform: uppercase;
+
+        font-family: @bx-font-family-button;
+        font-size: @bx-font-size-button;
+        font-weight: @bx-font-weight-button;
+        color: @bx-font-color-button;
+        
+        padding-top: 0px;
+        padding-bottom: 0px;
+    }
+    .bx-btn.bx-btn-primary {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button-primary;
+        line-height: (@bx-height-button-primary - 0.125 * @bx-border-width-button-primary);
+
+        .background-color (@bx-color-button-primary);
+
+        border-width: @bx-border-width-button-primary;
+        border-style: solid;
+        border-color: @bx-color-border-button-primary;
+
+        border-radius: @bx-border-radius-button-primary;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-button-primary;
+        -moz-box-shadow: @bx-shadow-button-primary;
+        box-shadow: @bx-shadow-button-primary;
+
+        text-shadow: @bx-shadow-font-button-primary;
+
+        font-family: @bx-font-family-button-primary;
+        font-size: @bx-font-size-button-primary;
+        font-weight: @bx-font-weight-button-primary;
+        color: @bx-font-color-button-primary;
+    }
+    .bx-btn-height {
+        height: @bx-height-button;
+        line-height: @bx-height-button;
+    }
+    .bx-btn-border {
+        border-width: @bx-border-width-button;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn-height.bx-btn-primary {
+        height: @bx-height-button-primary;
+        line-height: @bx-height-button-primary;
+    }
+    .bx-btn-border.bx-btn-primary {
+        border-width: @bx-border-width-button-primary;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn:hover,
+    .bx-btn:active {
+        border-width: @bx-border-width-button;
+        border-style: solid;
+    }
+    .bx-btn:hover {
+        border-color: @bx-color-border-button-hover;
+
+        .background-color (@bx-color-button-hover);
+
+        color: @bx-font-color-button-hover;
+    }
+    .bx-btn:active {
+        border-color: @bx-color-border-button-click;
+
+        .background-color (@bx-color-button-click);
+        box-shadow: @bx-shadow-color-button-click;
+
+        color: @bx-font-color-button-click;
+    }
+    .bx-btn.bx-btn-primary:hover,
+    .bx-btn.bx-btn-primary:active {
+        border-width: @bx-border-width-button-primary;
+        border-style: solid;
+    }
+    .bx-btn.bx-btn-primary:hover {
+        border-color: @bx-color-border-button-primary-hover;
+
+        .background-color (@bx-color-button-primary-hover);
+
+        color: @bx-font-color-button-primary-hover;
+    }
+    .bx-btn.bx-btn-primary:active {
+        border-color: @bx-color-border-button-primary-click;
+
+        .background-color (@bx-color-button-primary-click);
+        box-shadow: @bx-shadow-color-button-primary-click;
+
+        color: @bx-font-color-button-primary-click;
+    }
+    .bx-btn .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button;
+    }
+    .bx-btn.bx-btn-primary .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button-primary;
+    }
+    .bx-btn:hover .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button-hover;
+    }
+    .bx-btn:active .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button-click;
+    }
+    .bx-btn.bx-btn-primary:hover .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button-primary-hover;
+    }
+    .bx-btn.bx-btn-primary:active .sys-icon:not(.sys-colored) {
+        color: @bx-font-color-button-primary-click;
+    }
+
+    /* button (large) */
+    .bx-btn.bx-btn-large {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button-large;
+        line-height: (@bx-height-button-large - 0.125 * @bx-border-width-button-large);
+
+        .background-color (@bx-color-button-large);
+
+        border-width: @bx-border-width-button-large;
+        border-style: solid;
+        border-color: @bx-color-border-button-large;
+
+        border-radius: @bx-border-radius-button-large;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-button-large;
+        -moz-box-shadow: @bx-shadow-button-large;
+        box-shadow: @bx-shadow-button-large;
+
+        text-shadow: @bx-shadow-font-button-large;
+
+        font-family: @bx-font-family-button-large;
+        font-size: @bx-font-size-button-large;
+        font-weight: @bx-font-weight-button-large;
+        color: @bx-font-color-button-large;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button-large-primary;
+        line-height: (@bx-height-button-large-primary - 0.125 * @bx-border-width-button-large-primary);
+
+        .background-color (@bx-color-button-large-primary);
+
+        border-width: @bx-border-width-button-large-primary;
+        border-style: solid;
+        border-color: @bx-color-border-button-large-primary;
+
+        border-radius: @bx-border-radius-button-large-primary;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-button-large-primary;
+        -moz-box-shadow: @bx-shadow-button-large-primary;
+        box-shadow: @bx-shadow-button-large-primary;
+
+        text-shadow: @bx-shadow-font-button-large-primary;
+
+        font-family: @bx-font-family-button-large-primary;
+        font-size: @bx-font-size-button-large-primary;
+        font-weight: @bx-font-weight-button-large-primary;
+        color: @bx-font-color-button-large-primary;
+    }
+    .bx-btn-large-height {
+        height: @bx-height-button-large;
+        line-height: @bx-height-button-large;
+    }
+    .bx-btn-large-height.bx-btn-primary {
+        height: @bx-height-button-large-primary;
+        line-height: @bx-height-button-large-primary;
+    }
+    .bx-btn-large-border {
+        border-width: @bx-border-width-button-large;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn-large-border.bx-btn-primary {
+        border-width: @bx-border-width-button-large-primary;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn.bx-btn-large:hover,
+    .bx-btn.bx-btn-large:active {
+        border-width: @bx-border-width-button-large;
+        border-style: solid;
+    }
+    .bx-btn.bx-btn-large:hover {
+        border-color: @bx-color-border-button-large-hover;
+
+        .background-color (@bx-color-button-large-hover);
+
+        color: @bx-font-color-button-large-hover;
+    }
+    .bx-btn.bx-btn-large:active {
+        border-color: @bx-color-border-button-large-click;
+
+        .background-color (@bx-color-button-large-click);
+        box-shadow: @bx-shadow-color-button-click;
+
+        color: @bx-font-color-button-large-click;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary:hover,
+    .bx-btn.bx-btn-large.bx-btn-primary:active {
+        border-width: @bx-border-width-button-large-primary;
+        border-style: solid;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary:hover {
+        border-color: @bx-color-border-button-large-primary-hover;
+
+        .background-color (@bx-color-button-large-primary-hover);
+
+        color: @bx-font-color-button-large-primary-hover;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary:active {
+        border-color: @bx-color-border-button-large-primary-click;
+
+        .background-color (@bx-color-button-large-primary-click);
+        box-shadow: @bx-shadow-color-button-primary-click;
+
+        color: @bx-font-color-button-large-primary-click;
+    }
+    .bx-btn.bx-btn-large .sys-icon {
+        color: @bx-font-color-button-large;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary .sys-icon {
+        color: @bx-font-color-button-large-primary;
+    }
+    .bx-btn.bx-btn-large:hover .sys-icon {
+        color: @bx-font-color-button-large-hover;
+    }
+    .bx-btn.bx-btn-large:active .sys-icon {
+        color: @bx-font-color-button-large-click;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary:hover .sys-icon {
+        color: @bx-font-color-button-large-primary-hover;
+    }
+    .bx-btn.bx-btn-large.bx-btn-primary:active .sys-icon {
+        color: @bx-font-color-button-large-primary-click;
+    }
+
+    /* button (small) */
+    .bx-btn.bx-btn-small {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button-small;
+        line-height: (@bx-height-button-small - 0.125 * @bx-border-width-button-small);
+
+        .background-color (@bx-color-button-small);
+
+        border-width: @bx-border-width-button-small;
+        border-style: solid;
+        border-color: @bx-color-border-button-small;
+
+        border-radius: @bx-border-radius-button-small;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-button-small;
+        -moz-box-shadow: @bx-shadow-button-small;
+        box-shadow: @bx-shadow-button-small;
+
+        text-shadow: @bx-shadow-font-button-small;
+
+        font-family: @bx-font-family-button-small;
+        font-size: @bx-font-size-button-small;
+        font-weight: @bx-font-weight-button-small;
+        color: @bx-font-color-button-small;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary {
+        .box-sizing(@base-input-box-sizing);
+
+        height: @bx-height-button-small-primary;
+        line-height: (@bx-height-button-small-primary - 0.125 * @bx-border-width-button-small-primary);
+
+        .background-color (@bx-color-button-small-primary);
+
+        border-width: @bx-border-width-button-small-primary;
+        border-style: solid;
+        border-color: @bx-color-border-button-small-primary;
+
+        border-radius: @bx-border-radius-button-small-primary;
+        background-clip: padding-box;
+
+        -webkit-box-shadow: @bx-shadow-button-small-primary;
+        -moz-box-shadow: @bx-shadow-button-small-primary;
+        box-shadow: @bx-shadow-button-small-primary;
+
+        text-shadow: @bx-shadow-font-button-small-primary;
+
+        font-family: @bx-font-family-button-small-primary;
+        font-size: @bx-font-size-button-small-primary;
+        font-weight: @bx-font-weight-button-small-primary;
+        color: @bx-font-color-button-small-primary;
+    }
+    .bx-btn-small-height {
+        height: @bx-height-button-small;
+        line-height: @bx-height-button-small;
+    }
+    .bx-btn-small-height.bx-btn-primary {
+        height: @bx-height-button-small-primary;
+        line-height: @bx-height-button-small-primary;
+    }
+    .bx-btn-small-border {
+        border-width: @bx-border-width-button-small;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn-small-border.bx-btn-primary {
+        border-width: @bx-border-width-button-small-primary;
+        border-style: solid;
+        border-color: transparent;
+    }
+    .bx-btn.bx-btn-small:hover,
+    .bx-btn.bx-btn-small:active {
+        border-width: @bx-border-width-button-small;
+        border-style: solid;
+    }
+    .bx-btn.bx-btn-small:hover {
+        border-color: @bx-color-border-button-small-hover;
+
+        .background-color (@bx-color-button-small-hover);
+
+        color: @bx-font-color-button-small-hover;
+    }
+    .bx-btn.bx-btn-small:active {
+        border-color: @bx-color-border-button-small-click;
+
+        .background-color (@bx-color-button-small-click);
+        box-shadow: @bx-shadow-color-button-click;
+
+        color: @bx-font-color-button-small-click;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary:hover,
+    .bx-btn.bx-btn-small.bx-btn-primary:active {
+        border-width: @bx-border-width-button-small-primary;
+        border-style: solid;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary:hover {
+        border-color: @bx-color-border-button-small-primary-hover;
+
+        .background-color (@bx-color-button-small-primary-hover);
+
+        color: @bx-font-color-button-small-primary-hover;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary:active {
+        border-color: @bx-color-border-button-small-primary-click;
+
+        .background-color (@bx-color-button-small-primary-click);
+        box-shadow: @bx-shadow-color-button-primary-click;
+
+        color: @bx-font-color-button-small-primary-click;
+    }
+    .bx-btn.bx-btn-small .sys-icon {
+        color: @bx-font-color-button-small;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary .sys-icon {
+        color: @bx-font-color-button-small-primary;
+    }
+    .bx-btn.bx-btn-small:hover .sys-icon {
+        color: @bx-font-color-button-small-hover;
+    }
+    .bx-btn.bx-btn-small:active .sys-icon {
+        color: @bx-font-color-button-small-click;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary:hover .sys-icon {
+        color: @bx-font-color-button-small-primary-hover;
+    }
+    .bx-btn.bx-btn-small.bx-btn-primary:active .sys-icon {
+        color: @bx-font-color-button-small-primary-click;
+    }
+
+
+    /*--- Menus: Mobile Dropdown ---*/
+    .bx-lcd-menu-dropdown.cd-dropdown,
+    .bx-lcd-menu-dropdown.cd-dropdown .cd-dropdown-title {
+        background-color: @bx-color-header;
+    }
+
+    .bx-lcd-mdd-search .bx-page-block-container input[type="text"]::-webkit-input-placeholder {
+      color: @bx-font-color-grayed;
+    }
+    .bx-lcd-mdd-search .bx-page-block-container input[type="text"]::-moz-placeholder {
+      color: @bx-font-color-grayed;
+    }
+    .bx-lcd-mdd-search .bx-page-block-container input[type="text"]:-moz-placeholder {
+      color: @bx-font-color-grayed;
+    }
+    .bx-lcd-mdd-search .bx-page-block-container input[type="text"]:-ms-input-placeholder {
+      color: @bx-font-color-grayed;
+    }
+
+
+    /*--- Alerts: Toolbar ---*/
+    ul.bx-menu-toolbar li a .bx-menu-item-addon {
+        border: 0.125rem solid @bx-color-header;
+    }
+    ul.bx-menu-toolbar li a .bx-menu-item-addon.bx-def-unit-alert {
+        top: -(@bx-font-size-default + 2) / 2;
+        right: -(@bx-font-size-default + 2) / 2;
+    }
+    ul.bx-menu-toolbar li a .bx-menu-item-addon.bx-def-unit-alert-small {
+        top: -(@bx-font-size-small + 5) / 2;
+        right: -(@bx-font-size-small + 5) / 2
+    }
+    ul.bx-menu-toolbar li a .bx-menu-item-addon.bx-def-unit-alert-middle {
+        top: -(@bx-font-size-middle + 2) / 2;
+        right: -(@bx-font-size-middle + 2) / 2;
+    }
+
+
+    /*--- Timeline -> Card: Annachmants ---*/
+    div.bx-tl-item div.bx-tl-item-images.bx-tl-ii-gallery div.bx-tl-item-image img,
+    div.bx-tl-item div.bx-tl-item-attachments.bx-tl-ia-gallery div.bx-tl-item-attachment img,
+    div.bx-tl-item .bx-tl-item-links .bx-tl-item-link {
+        border-radius: @bx-border-radius-box;
+    }
+    div.bx-tl-item div.bx-tl-item-images.bx-tl-ii-gallery div.bx-tl-item-image img,
+    div.bx-tl-item div.bx-tl-item-attachments.bx-tl-ia-gallery div.bx-tl-item-attachment img {
+        background-clip: padding-box;
+    }
+
+    /*--- Timeline Card -> Comments: Font size ---*/
+    div.bx-tl-item-comments-holder div.bx-tl-item-comments .cmts.cmts-margin {
+        .font-size(@bx-font-size-default);
+    }
+}
+
+.bx-media-phone .@{bx-root-class-name} {
+    /* main menu */
+    .cd-dropdown .cd-dropdown-content a, 
+    .cd-dropdown .cd-dropdown-content ul a {
+        text-shadow: @bx-shadow-font-menu-main;
+
+        font-family: @bx-font-family-menu-main;
+        font-size: @bx-font-size-menu-main;
+        font-weight: @bx-font-weight-menu-main;
+        color: @bx-font-color-menu-main;
+    }
+    .cd-dropdown .cd-dropdown-content a:hover, 
+    .cd-dropdown .cd-dropdown-content ul a:hover,
+    .cd-dropdown .cd-dropdown-content a:hover .sys-icon, 
+    .cd-dropdown .cd-dropdown-content ul a:hover .sys-icon,
+    .cd-dropdown .cd-dropdown-content a:hover .sys-icon-a, 
+    .cd-dropdown .cd-dropdown-content ul a:hover .sys-icon-a {
+        color: @bx-font-color-menu-main-hover;
+    }
+
+    .go-back a::before, 
+    .go-back a::after,
+    .has-children > a::before, 
+    .has-children > a::after, 
+    .cd-dropdown .cd-close::after, 
+    .cd-dropdown .cd-close::before {
+        background-color: @bx-font-color-menu-main;
+    }
+
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a .sys-icon,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a .sys-icon-a {
+        color: @bx-font-color-menu-account;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .sys-icon,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a .sys-icon-a {
+        color: @bx-font-color-menu-account-active;
+    }
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover .sys-icon,
+    #bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover .sys-icon-a {
+        color: @bx-font-color-menu-account-hover;
+    }
+}
+
+/* viewport */
+html.bx-media-tablet {
+    font-size: @bx-viewport-font-tablet;
+}
+
+html.bx-media-phone {
+    font-size: @bx-viewport-font-mobile;
+}

+ 5 - 0
modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/designbox_10.html

@@ -0,0 +1,5 @@
+<!-- Design Box 10 [start]: Content only + padding -->
+<div class="bx-db-container bx-dbc-notitle bx-dbc-nobg">
+    <div class="bx-db-content bx-content-padding-block bx-clearfix">__designbox_content__</div>
+</div>
+<!-- Design Box 10 [ end ] -->

+ 5 - 0
modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/designbox_13.html

@@ -0,0 +1,5 @@
+<!-- Design Box 13 [start]: Content + background + padding -->
+<div class="bx-db-container bx-dbc-notitle bx-def-image-bg-block bx-def-color-bg-block bx-def-border-block bx-shadow-block">
+    <div class="bx-db-content bx-content-padding-block bx-clearfix">__designbox_content__</div>
+</div>
+<!-- Design Box 13 [ end ] -->

+ 5 - 0
modules/boonex/lucid/updates/13.0.4_13.0.5/source/data/template/system/designbox_3.html

@@ -0,0 +1,5 @@
+<!-- Design Box 3 [start]: Content + background -->
+<div class="bx-db-container bx-dbc-notitle bx-dbc-nopadding bx-def-image-bg-block bx-def-color-bg-block bx-def-border-block bx-shadow-block">
+    <div class="bx-db-content bx-clearfix">__designbox_content__</div>
+</div>
+<!-- Design Box 3 [ end ] -->

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません