underpost 2.8.86 → 2.8.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.env.development +39 -2
  2. package/.env.production +42 -2
  3. package/.env.test +39 -2
  4. package/.github/workflows/ghpkg.ci.yml +1 -1
  5. package/.github/workflows/npmpkg.ci.yml +1 -1
  6. package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -5
  7. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  8. package/.github/workflows/release.cd.yml +3 -3
  9. package/README.md +76 -2
  10. package/bin/build.js +5 -0
  11. package/bin/deploy.js +93 -27
  12. package/bin/file.js +8 -4
  13. package/bin/util.js +1 -56
  14. package/cli.md +16 -5
  15. package/conf.js +33 -7
  16. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  17. package/manifests/deployment/dd-test-development/deployment.yaml +174 -0
  18. package/manifests/deployment/dd-test-development/proxy.yaml +51 -0
  19. package/manifests/deployment/mongo-express/deployment.yaml +12 -12
  20. package/manifests/maas/nvim.sh +91 -0
  21. package/package.json +8 -15
  22. package/src/api/core/core.router.js +2 -1
  23. package/src/api/default/default.controller.js +6 -1
  24. package/src/api/default/default.router.js +6 -2
  25. package/src/api/default/default.service.js +10 -1
  26. package/src/api/document/document.controller.js +66 -0
  27. package/src/api/document/document.model.js +51 -0
  28. package/src/api/document/document.router.js +24 -0
  29. package/src/api/document/document.service.js +125 -0
  30. package/src/api/file/file.controller.js +15 -1
  31. package/src/api/file/file.router.js +2 -1
  32. package/src/api/file/file.service.js +28 -8
  33. package/src/api/test/test.router.js +1 -1
  34. package/src/api/user/postman_collection.json +216 -0
  35. package/src/api/user/user.controller.js +25 -60
  36. package/src/api/user/user.model.js +29 -7
  37. package/src/api/user/user.router.js +40 -8
  38. package/src/api/user/user.service.js +86 -35
  39. package/src/cli/baremetal.js +33 -3
  40. package/src/cli/cloud-init.js +11 -0
  41. package/src/cli/cluster.js +4 -23
  42. package/src/cli/cron.js +0 -1
  43. package/src/cli/db.js +0 -19
  44. package/src/cli/deploy.js +67 -52
  45. package/src/cli/fs.js +1 -0
  46. package/src/cli/index.js +9 -1
  47. package/src/cli/lxd.js +7 -0
  48. package/src/cli/repository.js +44 -6
  49. package/src/cli/run.js +56 -9
  50. package/src/cli/ssh.js +20 -6
  51. package/src/client/Default.index.js +42 -1
  52. package/src/client/components/core/Account.js +10 -2
  53. package/src/client/components/core/AgGrid.js +30 -8
  54. package/src/client/components/core/Auth.js +99 -56
  55. package/src/client/components/core/BtnIcon.js +3 -2
  56. package/src/client/components/core/CalendarCore.js +2 -3
  57. package/src/client/components/core/CommonJs.js +1 -2
  58. package/src/client/components/core/Content.js +15 -12
  59. package/src/client/components/core/Css.js +2 -1
  60. package/src/client/components/core/CssCore.js +18 -1
  61. package/src/client/components/core/Docs.js +5 -5
  62. package/src/client/components/core/FileExplorer.js +3 -3
  63. package/src/client/components/core/FullScreen.js +19 -28
  64. package/src/client/components/core/Input.js +22 -16
  65. package/src/client/components/core/JoyStick.js +2 -2
  66. package/src/client/components/core/LoadingAnimation.js +2 -2
  67. package/src/client/components/core/LogIn.js +16 -23
  68. package/src/client/components/core/LogOut.js +5 -1
  69. package/src/client/components/core/Logger.js +4 -1
  70. package/src/client/components/core/Modal.js +102 -87
  71. package/src/client/components/core/ObjectLayerEngine.js +229 -4
  72. package/src/client/components/core/ObjectLayerEngineModal.js +442 -0
  73. package/src/client/components/core/Pagination.js +207 -0
  74. package/src/client/components/core/Panel.js +10 -10
  75. package/src/client/components/core/PanelForm.js +130 -33
  76. package/src/client/components/core/Recover.js +2 -2
  77. package/src/client/components/core/Router.js +210 -34
  78. package/src/client/components/core/SignUp.js +1 -2
  79. package/src/client/components/core/Stream.js +1 -1
  80. package/src/client/components/core/ToggleSwitch.js +15 -1
  81. package/src/client/components/core/VanillaJs.js +3 -84
  82. package/src/client/components/core/Worker.js +2 -2
  83. package/src/client/components/default/LogInDefault.js +0 -6
  84. package/src/client/components/default/LogOutDefault.js +0 -16
  85. package/src/client/components/default/MenuDefault.js +97 -44
  86. package/src/client/components/default/RoutesDefault.js +5 -2
  87. package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
  88. package/src/client/services/core/core.service.js +8 -20
  89. package/src/client/services/default/default.management.js +115 -18
  90. package/src/client/services/default/default.service.js +13 -4
  91. package/src/client/services/document/document.service.js +97 -0
  92. package/src/client/services/file/file.service.js +2 -0
  93. package/src/client/services/test/test.service.js +3 -0
  94. package/src/client/services/user/user.management.js +6 -0
  95. package/src/client/services/user/user.service.js +15 -4
  96. package/src/client/ssr/Render.js +1 -1
  97. package/src/client/ssr/head/DefaultScripts.js +3 -0
  98. package/src/client/ssr/head/Seo.js +1 -0
  99. package/src/index.js +24 -2
  100. package/src/runtime/lampp/Lampp.js +89 -2
  101. package/src/runtime/xampp/Xampp.js +48 -1
  102. package/src/server/auth.js +519 -155
  103. package/src/server/backup.js +2 -2
  104. package/src/server/client-build-docs.js +1 -1
  105. package/src/server/client-build.js +4 -12
  106. package/src/server/client-icons.js +6 -78
  107. package/src/server/conf.js +144 -141
  108. package/src/server/process.js +2 -1
  109. package/src/server/proxy.js +1 -1
  110. package/src/server/runtime.js +136 -288
  111. package/src/server/ssl.js +1 -2
  112. package/src/server/ssr.js +85 -0
  113. package/src/server/start.js +4 -4
  114. package/src/server/valkey.js +2 -1
  115. package/test/api.test.js +3 -2
  116. package/bin/cyberia0.js +0 -78
@@ -7,7 +7,7 @@ import { loggerFactory } from './Logger.js';
7
7
  import { RichText } from './RichText.js';
8
8
  import { ToggleSwitch } from './ToggleSwitch.js';
9
9
  import { Translate } from './Translate.js';
10
- import { htmls, s } from './VanillaJs.js';
10
+ import { htmls, htmlStrSanitize, s } from './VanillaJs.js';
11
11
  const logger = loggerFactory(import.meta);
12
12
 
13
13
  const fileFormDataFactory = (e, extensions) => {
@@ -61,21 +61,27 @@ const Input = {
61
61
  };
62
62
  });
63
63
 
64
- const inputElement = html` <input
65
- type="${options?.type ? options.type : 'text'}"
66
- class="${options.inputClass ? options.inputClass : 'in wfa'} ${id}"
67
- ${options?.min !== undefined ? `min="${options.min}"` : ''}
68
- placeholder${options?.placeholder ? `="${options.placeholder}"` : ''}
69
- ${options?.value !== undefined ? `value="${options.value}"` : ''}
70
- ${options?.autocomplete ? `autocomplete="${options.autocomplete}"` : ''}
71
- ${options?.disabled ? `disabled` : ''}
72
- ${options?.name !== undefined ? `name="${options.name}"` : ''}
73
- ${options?.pattern !== undefined ? `pattern="${options.pattern}"` : ''}
74
- ${options?.pattern === undefined && options.type === 'tel' ? `pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"` : ''}
75
- ${options?.required ? ` required ` : ''}
76
- ${options?.accept ? `accept="${options.accept}"` : ''}
77
- ${options?.multiple ? `multiple="multiple"` : ''}
78
- />
64
+ const labelValue = htmlStrSanitize(options.label) ? htmlStrSanitize(options.label) : id;
65
+
66
+ const inputElement = html` <label for="${id}-name">
67
+ <span class="hide">${labelValue}</span>
68
+ <input
69
+ type="${options?.type ? options.type : 'text'}"
70
+ class="${options.inputClass ? options.inputClass : 'in wfa'} ${id}"
71
+ ${options?.min !== undefined ? `min="${options.min}"` : ''}
72
+ ${options?.max !== undefined ? `max="${options.max}"` : ''}
73
+ placeholder${options?.placeholder ? `="${options.placeholder}"` : ''}
74
+ ${options?.value !== undefined ? `value="${options.value}"` : ''}
75
+ ${options?.autocomplete ? `autocomplete="${options.autocomplete}"` : ''}
76
+ ${options?.disabled ? `disabled` : ''}
77
+ ${options?.name !== undefined ? `name="${options.name}"` : `name='${id}-name'`}
78
+ ${options?.pattern !== undefined ? `pattern="${options.pattern}"` : ''}
79
+ ${options?.pattern === undefined && options.type === 'tel' ? `pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"` : ''}
80
+ ${options?.required ? ` required ` : ''}
81
+ ${options?.accept ? `accept="${options.accept}"` : ''}
82
+ ${options?.multiple ? `multiple="multiple"` : ''}
83
+ id="${id}-name"
84
+ /></label>
79
85
  <div class="${id}-input-extension input-info input-extension ${options?.extension ? '' : 'hide'}">
80
86
  ${options?.extension ? await options.extension() : ''}
81
87
  </div>`;
@@ -1,7 +1,7 @@
1
1
  import JoystickController from 'joystick-controller';
2
2
  import { getDirection, getId } from './CommonJs.js';
3
- import { loggerFactory } from './Logger.js';
4
- import { append, getProxyPath, s } from './VanillaJs.js';
3
+ import { append, s } from './VanillaJs.js';
4
+ import { getProxyPath } from './Router.js';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
7
7
 
@@ -1,9 +1,9 @@
1
- import { CoreService } from '../../services/core/core.service.js';
2
1
  import { BtnIcon } from './BtnIcon.js';
3
2
  import { s4 } from './CommonJs.js';
4
3
  import { darkTheme, renderCssAttr, subThemeManager } from './Css.js';
5
4
  import { loggerFactory } from './Logger.js';
6
- import { append, getAllChildNodes, getProxyPath, htmls, s, sa } from './VanillaJs.js';
5
+ import { append, htmls, s } from './VanillaJs.js';
6
+ import { getProxyPath } from './Router.js';
7
7
 
8
8
  const logger = loggerFactory(import.meta);
9
9
 
@@ -24,8 +24,9 @@ const LogIn = {
24
24
  Event: {},
25
25
  Trigger: async function (options) {
26
26
  const { user } = options;
27
- await Webhook.register({ user });
28
27
  for (const eventKey of Object.keys(this.Event)) await this.Event[eventKey](options);
28
+ if (!user || user.role === 'guest') return;
29
+ await Webhook.register({ user });
29
30
  if (s(`.session`))
30
31
  htmls(
31
32
  `.session`,
@@ -72,19 +73,18 @@ const LogIn = {
72
73
  imageSrc,
73
74
  };
74
75
  }
76
+ htmls(
77
+ `.action-btn-profile-log-in-render`,
78
+ html`<div class="abs center top-box-profile-img-container">
79
+ <img
80
+ class="abs center top-box-profile-img"
81
+ ${this.Scope.user.main.model.user.profileImage
82
+ ? `src="${this.Scope.user.main.model.user.profileImage.imageSrc}"`
83
+ : ``}
84
+ />
85
+ </div>`,
86
+ );
75
87
  }
76
-
77
- htmls(
78
- `.action-btn-profile-log-in-render`,
79
- html`<div class="abs center top-box-profile-img-container">
80
- <img
81
- class="abs center top-box-profile-img"
82
- ${this.Scope.user.main.model.user.profileImage
83
- ? `src="${this.Scope.user.main.model.user.profileImage.imageSrc}"`
84
- : ``}
85
- />
86
- </div>`,
87
- );
88
88
  },
89
89
  Render: async function () {
90
90
  setTimeout(async () => {
@@ -103,13 +103,7 @@ const LogIn = {
103
103
  if ('model' in inputData) body[inputData.model] = s(`.${inputData.id}`).value;
104
104
  }
105
105
  const result = await UserService.post({ id: 'auth', body });
106
- if (result.status === 'success') {
107
- await Auth.sessionIn(result);
108
- setTimeout(() => {
109
- if (s(`.modal-log-in`)) s(`.btn-close-modal-log-in`).click();
110
- if (s(`.modal-sign-up`)) s(`.btn-close-modal-sign-up`).click();
111
- });
112
- }
106
+
113
107
  if (result.status === 'error' && result.message.match('attempts')) {
114
108
  htmls(`.login-attempt-warn-value`, result.message.split(':')[1]);
115
109
  s(`.login-attempt-warn-container`).classList.remove('hide');
@@ -119,6 +113,8 @@ const LogIn = {
119
113
  htmls(`.login-attempt-warn-value0`, result.message.split(':')[1]);
120
114
  s(`.login-attempt-warn-container0`).classList.remove('hide');
121
115
  } else s(`.login-attempt-warn-container0`).classList.add('hide');
116
+
117
+ if (result.status === 'success') await Auth.sessionIn(result);
122
118
  NotificationManager.Push({
123
119
  html: result.status === 'success' ? Translate.Render(`${result.status}-user-log-in`) : result.message,
124
120
  status: result.status,
@@ -189,9 +185,6 @@ const LogIn = {
189
185
  </form>
190
186
  `;
191
187
  },
192
- cleanMainUser: () => {
193
- LogIn.Scope.user.main.model.user = {};
194
- },
195
188
  };
196
189
 
197
190
  export { LogIn };
@@ -4,11 +4,11 @@ import { LogIn } from './LogIn.js';
4
4
  import { Translate } from './Translate.js';
5
5
  import { htmls, s } from './VanillaJs.js';
6
6
  import { Webhook } from './Webhook.js';
7
+ import { NotificationManager } from './NotificationManager.js';
7
8
 
8
9
  const LogOut = {
9
10
  Event: {},
10
11
  Trigger: async function (options) {
11
- LogIn.cleanMainUser();
12
12
  await Webhook.unregister();
13
13
  for (const eventKey of Object.keys(this.Event)) await this.Event[eventKey](options);
14
14
  if (s(`.session`))
@@ -41,6 +41,10 @@ const LogOut = {
41
41
  s('.btn-log-out').onclick = async (e) => {
42
42
  e.preventDefault();
43
43
  await Auth.sessionOut();
44
+ NotificationManager.Push({
45
+ html: Translate.Render(`success-logout`),
46
+ status: 'success',
47
+ });
44
48
  };
45
49
  });
46
50
  // Translate.Render('confirm-logout')
@@ -1,4 +1,6 @@
1
- const loggerFactory = (meta) => {
1
+ import { getCurrentTrace } from './CommonJs.js';
2
+
3
+ const loggerFactory = (meta, options = { trace: false }) => {
2
4
  meta = meta.url.split('/').pop();
3
5
  const types = ['error', 'warn', 'info', 'debug'];
4
6
  const logger = {
@@ -9,6 +11,7 @@ const loggerFactory = (meta) => {
9
11
  console.info = () => null;
10
12
  console.warn = () => null;
11
13
  }
14
+ if (options.trace === true) args.push(getCurrentTrace().split('Logger.js:23')[1]);
12
15
  return location.hostname === 'localhost'
13
16
  ? console[type](`[${meta}] ${new Date().toISOString()} ${type}:`, ...args)
14
17
  : null;
@@ -1,16 +1,6 @@
1
- import { cap, getId, newInstance } from './CommonJs.js';
1
+ import { getId, newInstance, s4 } from './CommonJs.js';
2
2
  import { Draggable } from '@neodrag/vanilla';
3
- import {
4
- append,
5
- s,
6
- prepend,
7
- setPath,
8
- getProxyPath,
9
- htmls,
10
- sa,
11
- getAllChildNodes,
12
- isActiveElement,
13
- } from './VanillaJs.js';
3
+ import { append, s, prepend, htmls, sa, getAllChildNodes, isActiveElement } from './VanillaJs.js';
14
4
  import { BtnIcon } from './BtnIcon.js';
15
5
  import { Responsive } from './Responsive.js';
16
6
  import { loggerFactory } from './Logger.js';
@@ -24,18 +14,25 @@ import {
24
14
  renderStatus,
25
15
  renderCssAttr,
26
16
  } from './Css.js';
27
- import { setDocTitle, closeModalRouteChangeEvent, handleModalViewRoute } from './Router.js';
17
+ import {
18
+ setDocTitle,
19
+ closeModalRouteChangeEvent,
20
+ handleModalViewRoute,
21
+ getProxyPath,
22
+ setPath,
23
+ coreUI,
24
+ } from './Router.js';
28
25
  import { NotificationManager } from './NotificationManager.js';
29
26
  import { EventsUI } from './EventsUI.js';
30
27
  import { Translate } from './Translate.js';
31
28
  import { Input, isTextInputFocused } from './Input.js';
32
- import { Validator } from './Validator.js';
33
29
  import { DropDown } from './DropDown.js';
34
30
  import { Keyboard } from './Keyboard.js';
35
31
  import { Badge } from './Badge.js';
36
32
  import { Worker } from './Worker.js';
33
+ import { Scroll } from './Scroll.js';
37
34
 
38
- const logger = loggerFactory(import.meta);
35
+ const logger = loggerFactory(import.meta, { trace: true });
39
36
 
40
37
  const Modal = {
41
38
  Data: {},
@@ -51,6 +48,7 @@ const Modal = {
51
48
  RouterInstance: {},
52
49
  disableTools: [],
53
50
  observer: false,
51
+ disableBoxShadow: false,
54
52
  },
55
53
  ) {
56
54
  if (options.heightBottomBar === undefined) options.heightBottomBar = 50;
@@ -89,6 +87,16 @@ const Modal = {
89
87
  onHome: {},
90
88
  homeModals: options.homeModals ? options.homeModals : [],
91
89
  query: options.query ? `${window.location.search}` : undefined,
90
+ getTop: () => window.innerHeight - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar),
91
+ getHeight: () => {
92
+ return (
93
+ window.innerHeight -
94
+ (s(`.main-body-btn-ui-close`) && !s(`.main-body-btn-ui-close`).classList.contains('hide')
95
+ ? (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
96
+ (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
97
+ : 0)
98
+ );
99
+ },
92
100
  };
93
101
 
94
102
  if (idModal !== 'main-body' && options.mode !== 'view') {
@@ -117,12 +125,7 @@ const Modal = {
117
125
 
118
126
  Responsive.Event[`view-${idModal}`] = () => {
119
127
  if (!this.Data[idModal]) return delete Responsive.Event[`view-${idModal}`];
120
- if (this.Data[idModal].slideMenu)
121
- s(`.${idModal}`).style.height = `${
122
- window.innerHeight -
123
- (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
124
- (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
125
- }px`;
128
+ if (this.Data[idModal].slideMenu) s(`.${idModal}`).style.height = `${this.Data[idModal].getHeight()}px`;
126
129
  };
127
130
  Responsive.Event[`view-${idModal}`]();
128
131
 
@@ -185,9 +188,7 @@ const Modal = {
185
188
  htmls(
186
189
  `.default-slide-menu-top-bar-fix-title-container`,
187
190
  html`
188
- <div class="inl default-slide-menu-top-bar-fix-title-container-text">
189
- ${options.RouterInstance.BannerAppTemplate}
190
- </div>
191
+ <div class="inl default-slide-menu-top-bar-fix-title-container-text">${options.title}</div>
191
192
  `,
192
193
  );
193
194
  } else
@@ -207,11 +208,7 @@ const Modal = {
207
208
  const { barConfig } = options;
208
209
  options.style = {
209
210
  position: 'absolute',
210
- height: `${
211
- window.innerHeight -
212
- (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
213
- (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
214
- }px`,
211
+ height: `${Modal.Data[idModal].getHeight()}px`,
215
212
  width: `${slideMenuWidth}px`,
216
213
  // 'overflow-x': 'hidden',
217
214
  // overflow: 'visible', // required for tooltip
@@ -239,11 +236,7 @@ const Modal = {
239
236
  if (this.Data[_idModal].slideMenu && this.Data[_idModal].slideMenu.id === idModal)
240
237
  this.Data[_idModal].slideMenu.callBack();
241
238
  }
242
- s(`.${idModal}`).style.height = `${
243
- window.innerHeight -
244
- (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
245
- (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
246
- }px`;
239
+ s(`.${idModal}`).style.height = `${Modal.Data[idModal].getHeight()}px`;
247
240
  if (s(`.main-body-top`)) {
248
241
  if (Modal.mobileModal()) {
249
242
  if (s(`.btn-menu-${idModal}`).classList.contains('hide') && collapseSlideMenuWidth !== slideMenuWidth)
@@ -281,6 +274,7 @@ const Modal = {
281
274
  s(`.btn-menu-${idModal}`).classList.remove('hide');
282
275
  s(`.${idModal}`).style.width = `${this.Data[idModal][options.mode].width}px`;
283
276
  s(`.html-${idModal}`).style.display = 'none';
277
+ // s(`.title-modal-${idModal}`).style.display = 'none';
284
278
  setTimeout(() => {
285
279
  s(`.main-body-btn-ui-menu-close`).classList.add('hide');
286
280
  s(`.main-body-btn-ui-menu-menu`).classList.remove('hide');
@@ -288,9 +282,6 @@ const Modal = {
288
282
  s(`.btn-bar-center-icon-menu`).classList.remove('hide');
289
283
  s(`.btn-bar-center-icon-close`).classList.add('hide');
290
284
  }
291
- });
292
- // s(`.title-modal-${idModal}`).style.display = 'none';
293
- setTimeout(() => {
294
285
  s(`.main-body-btn-container`).style[
295
286
  true || (options.mode && options.mode.match('right')) ? 'right' : 'left'
296
287
  ] = `${0}px`;
@@ -382,6 +373,7 @@ const Modal = {
382
373
  s(`.modal-menu`).style.top = '0px';
383
374
  s(`.main-body-btn-container`).style.top = '50px';
384
375
  s(`.main-body`).style.top = '0px';
376
+ s(`.main-body`).style.height = `${window.innerHeight}px`;
385
377
  for (const event of Object.keys(Modal.Data[idModal].onBarUiClose))
386
378
  Modal.Data[idModal].onBarUiClose[event]();
387
379
  } else {
@@ -394,6 +386,7 @@ const Modal = {
394
386
  s(`.slide-menu-top-bar`).classList.remove('hide');
395
387
  s(`.bottom-bar`).classList.remove('hide');
396
388
  s(`.main-body`).style.top = `${options.heightTopBar}px`;
389
+ s(`.main-body`).style.height = `${window.innerHeight - options.heightTopBar}px`;
397
390
  for (const event of Object.keys(Modal.Data[idModal].onBarUiOpen))
398
391
  Modal.Data[idModal].onBarUiOpen[event]();
399
392
  }
@@ -753,9 +746,12 @@ const Modal = {
753
746
  s(`.main-btn-${results[currentKeyBoardSearchBoxIndex].routerId}`).click();
754
747
  Modal.removeModal(searchBoxHistoryId);
755
748
  };
756
-
749
+ let boxHistoryDelayRender = 0;
757
750
  const searchBoxHistoryOpen = async () => {
758
- if (!s(`.${id}`)) {
751
+ if (boxHistoryDelayRender) return;
752
+ boxHistoryDelayRender = 1000;
753
+ setTimeout(() => (boxHistoryDelayRender = 0));
754
+ if (!s(`.${searchBoxHistoryId}`)) {
759
755
  const { barConfig } = await Themes[Css.currentTheme]();
760
756
  barConfig.buttons.maximize.disabled = true;
761
757
  barConfig.buttons.minimize.disabled = true;
@@ -763,7 +759,7 @@ const Modal = {
763
759
  barConfig.buttons.menu.disabled = true;
764
760
  barConfig.buttons.close.disabled = false;
765
761
  await Modal.Render({
766
- id,
762
+ id: searchBoxHistoryId,
767
763
  barConfig,
768
764
  title: html`<div class="search-box-recent-title">
769
765
  ${renderViewTitle({
@@ -791,8 +787,7 @@ const Modal = {
791
787
  dragDisabled: true,
792
788
  maximize: true,
793
789
  heightBottomBar: 0,
794
- heightTopBar: originHeightTopBar,
795
- barMode: options.barMode,
790
+ heightTopBar: options.heightTopBar,
796
791
  });
797
792
 
798
793
  // Bind hover/focus and click-outside to dismiss
@@ -964,6 +959,7 @@ const Modal = {
964
959
  heightBottomBar: originHeightBottomBar,
965
960
  barMode: options.barMode,
966
961
  observer: true,
962
+ disableBoxShadow: true,
967
963
  });
968
964
  const maxWidthInputSearchBox = 450;
969
965
  const paddingInputSearchBox = 5;
@@ -985,12 +981,7 @@ const Modal = {
985
981
  s(`.top-bar-search-box`).style.top = `${
986
982
  (originHeightTopBar - s(`.top-bar-search-box`).clientHeight) / 2
987
983
  }px`;
988
- if (this.Data[id].slideMenu)
989
- s(`.${id}`).style.height = `${
990
- window.innerHeight -
991
- (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
992
- (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
993
- }px`;
984
+ if (this.Data[id].slideMenu) s(`.${id}`).style.height = `${Modal.Data[id].getHeight()}px`;
994
985
  };
995
986
  Responsive.Event[`view-${id}`]();
996
987
  Keyboard.instanceMultiPressKey({
@@ -1119,9 +1110,7 @@ const Modal = {
1119
1110
  if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`];
1120
1111
  // <div class="in fll right-offset-menu-bottom-bar" style="height: 100%"></div>
1121
1112
  // s(`.right-offset-menu-bottom-bar`).style.width = `${window.innerWidth - slideMenuWidth}px`;
1122
- s(`.${id}`).style.top = `${
1123
- window.innerHeight - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
1124
- }px`;
1113
+ s(`.${id}`).style.top = `${Modal.Data[id].getTop()}px`;
1125
1114
  };
1126
1115
  Responsive.Event[`view-${id}`]();
1127
1116
  }
@@ -1293,11 +1282,7 @@ const Modal = {
1293
1282
  s(`.main-body-btn-ui-close`).classList.contains('hide') &&
1294
1283
  s(`.btn-restore-${id}`).style.display !== 'none'
1295
1284
  ? `${window.innerHeight}px`
1296
- : `${
1297
- window.innerHeight -
1298
- (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
1299
- (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
1300
- }px`;
1285
+ : `${Modal.Data[id].getHeight()}px`;
1301
1286
 
1302
1287
  if (
1303
1288
  s(`.main-body-btn-ui-close`).classList.contains('hide') &&
@@ -1314,6 +1299,15 @@ const Modal = {
1314
1299
  }
1315
1300
 
1316
1301
  await NotificationManager.RenderBoard(options);
1302
+
1303
+ const { removeEvent } = Scroll.setEvent('.main-body', async (payload) => {
1304
+ console.warn('scroll', payload);
1305
+ if (payload.scrollTop > 100) {
1306
+ if (!s(`.main-body-btn-ui-close`).classList.contains('hide')) s(`.main-body-btn-ui-close`).click();
1307
+
1308
+ removeEvent();
1309
+ }
1310
+ });
1317
1311
  });
1318
1312
  })();
1319
1313
  break;
@@ -1405,7 +1399,11 @@ const Modal = {
1405
1399
  }
1406
1400
  </style>
1407
1401
  ${renderStyleTag(`style-${idModal}`, `.${idModal}`, options)}
1408
- <div class="fix ${options && options.class ? options.class : ''} modal box-shadow ${idModal}">
1402
+ <div
1403
+ class="fix ${options && options.class ? options.class : ''} modal ${options.disableBoxShadow
1404
+ ? ''
1405
+ : 'box-shadow'} ${idModal === 'main-body' ? `${idModal} modal-home` : idModal}"
1406
+ >
1409
1407
  <div class="abs modal-handle-${idModal}"></div>
1410
1408
  <div class="in modal-html-${idModal}">
1411
1409
  <div class="stq bar-default-modal bar-default-modal-${idModal}">
@@ -1545,18 +1543,6 @@ const Modal = {
1545
1543
  s(`.btn-icon-menu-back`).classList.add('hide');
1546
1544
  if (s(`.menu-btn-container-main`)) s(`.menu-btn-container-main`).classList.remove('hide');
1547
1545
  };
1548
- this.onHomeRouterEvent = async () => {
1549
- for (const keyModal of Object.keys(this.Data)) {
1550
- if (
1551
- ![idModal, 'main-body-top', 'main-body'].concat(this.Data[idModal]?.homeModals || []).includes(keyModal)
1552
- )
1553
- if (s(`.btn-close-${keyModal}`)) s(`.btn-close-${keyModal}`).click();
1554
- backMenuButtonEvent();
1555
- }
1556
- if (s(`.btn-close-modal-menu`)) s(`.btn-close-modal-menu`).click();
1557
- setPath(getProxyPath());
1558
- setDocTitle();
1559
- };
1560
1546
  s(`.main-btn-home`).onclick = async () => {
1561
1547
  // await this.onHomeRouterEvent();
1562
1548
  s(`.action-btn-home`).click();
@@ -1777,13 +1763,8 @@ const Modal = {
1777
1763
  if (!s(`.${idModal}`)) return;
1778
1764
  this.removeModal(idModal);
1779
1765
  // Handle modal route change
1780
- if (options.route) {
1781
- closeModalRouteChangeEvent({
1782
- route: options.route,
1783
- RouterInstance: options.RouterInstance,
1784
- homeCid: Modal.homeCid,
1785
- });
1786
- }
1766
+ closeModalRouteChangeEvent({ closedId: idModal });
1767
+ // history.back();
1787
1768
  }, 300);
1788
1769
  };
1789
1770
  s(`.btn-close-${idModal}`).onclick = btnCloseEvent;
@@ -1918,11 +1899,7 @@ const Modal = {
1918
1899
  if (s(`.btn-restore-${idModal}`) && s(`.btn-restore-${idModal}`).style.display !== 'none') {
1919
1900
  s(`.${idModal}`).style.height = s(`.main-body-btn-ui-close`).classList.contains('hide')
1920
1901
  ? `${window.innerHeight}px`
1921
- : `${
1922
- window.innerHeight -
1923
- (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) -
1924
- (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
1925
- }px`;
1902
+ : `${Modal.Data[idModal].getHeight()}px`;
1926
1903
  }
1927
1904
  s(`.${idModal}`).style.top = s(`.main-body-btn-ui-close`).classList.contains('hide')
1928
1905
  ? `0px`
@@ -1981,7 +1958,45 @@ const Modal = {
1981
1958
  ...this.Data[idModal],
1982
1959
  };
1983
1960
  },
1984
- onHomeRouterEvent: () => {},
1961
+ onHomeRouterEvent: async () => {
1962
+ // 1. Get list of modals to close.
1963
+ const modalsToClose = Object.keys(Modal.Data).filter((idModal) => {
1964
+ const modal = Modal.Data[idModal];
1965
+ if (!modal) return false;
1966
+ // Don't close the core UI elements
1967
+
1968
+ if (coreUI.find((id) => idModal.startsWith(id))) {
1969
+ return false;
1970
+ }
1971
+ // Don't close modals that are part of the "home" screen itself
1972
+ const homeModals = Modal.Data['modal-menu']?.homeModals || [];
1973
+ if (homeModals.includes(idModal)) {
1974
+ return false;
1975
+ }
1976
+ return true;
1977
+ });
1978
+
1979
+ // 2. Navigate to home first, creating a new history entry.
1980
+ setPath(`${getProxyPath()}${location.search ?? ''}${location.hash ?? ''}`);
1981
+ setDocTitle();
1982
+
1983
+ // 3. Close the modals without them affecting the URL.
1984
+ for (const id of modalsToClose) {
1985
+ Modal.removeModal(id);
1986
+ }
1987
+
1988
+ // 4. Finally, handle UI cleanup for the slide-menu.
1989
+ if (s(`.menu-btn-container-children`)) htmls(`.menu-btn-container-children`, '');
1990
+ if (s(`.nav-title-display-modal-menu`)) htmls(`.nav-title-display-modal-menu`, '');
1991
+ if (s(`.nav-path-display-modal-menu`)) htmls(`.nav-path-display-modal-menu`, '');
1992
+ if (s(`.btn-icon-menu-back`)) s(`.btn-icon-menu-back`).classList.add('hide');
1993
+ if (s(`.menu-btn-container-main`)) s(`.menu-btn-container-main`).classList.remove('hide');
1994
+
1995
+ // And close the slide menu if it's open
1996
+ if (s(`.btn-close-modal-menu`) && !s(`.btn-close-modal-menu`).classList.contains('hide')) {
1997
+ s(`.btn-close-modal-menu`).click();
1998
+ }
1999
+ },
1985
2000
  currentTopModalId: '',
1986
2001
  zIndexSync: function ({ idModal }) {
1987
2002
  setTimeout(() => {
@@ -2010,11 +2025,6 @@ const Modal = {
2010
2025
  setTopModalCallback: function (idModal) {
2011
2026
  s(`.${idModal}`).style.zIndex = '4';
2012
2027
  this.currentTopModalId = `${idModal}`;
2013
- if (
2014
- this.Data[idModal].query &&
2015
- `${location.pathname}${window.location.search}` !== `${location.pathname}${this.Data[idModal].query}`
2016
- )
2017
- setPath(`${location.pathname}${this.Data[idModal].query}`);
2018
2028
  },
2019
2029
  mobileModal: () => window.innerWidth < 600 || window.innerHeight < 600,
2020
2030
  writeHTML: ({ idModal, html }) => htmls(`.html-${idModal}`, html),
@@ -2253,6 +2263,11 @@ const Modal = {
2253
2263
  s(`.bottom-bar`).classList.remove('hide');
2254
2264
  s(`.modal-menu`).classList.remove('hide');
2255
2265
  },
2266
+ RenderSeoSanitizer: async () => {
2267
+ sa('img').forEach((img) => {
2268
+ if (!img.getAttribute('alt')) img.setAttribute('alt', 'image ' + Worker.title + ' ' + s4());
2269
+ });
2270
+ },
2256
2271
  };
2257
2272
 
2258
2273
  const renderMenuLabel = ({ img, text, icon }) => {