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
@@ -33,6 +33,22 @@ const templateHTML = html`
33
33
  top: 0;
34
34
  pointer-events: none;
35
35
  }
36
+ .toolbar {
37
+ display: flex;
38
+ gap: 8px;
39
+ flex-wrap: wrap;
40
+ align-items: center;
41
+ }
42
+ .toolbar label {
43
+ display: inline-flex;
44
+ gap: 6px;
45
+ align-items: center;
46
+ }
47
+ .group {
48
+ display: inline-flex;
49
+ gap: 6px;
50
+ align-items: center;
51
+ }
36
52
  </style>
37
53
 
38
54
  <div class="wrap">
@@ -48,8 +64,34 @@ const templateHTML = html`
48
64
  <label>brush <input type="number" part="brush-size" min="1" value="1" /></label>
49
65
  <label>pixel-size <input type="number" part="pixel-size" min="1" value="16" /></label>
50
66
 
67
+ <!-- New: cell dimensions (width x height) -->
68
+ <label
69
+ >cells <input type="number" part="cell-width" min="1" value="16" style="width:6ch" /> x
70
+ <input type="number" part="cell-height" min="1" value="16" style="width:6ch"
71
+ /></label>
72
+
51
73
  <label class="switch"> <input type="checkbox" part="toggle-grid" /> grid </label>
52
74
 
75
+ <!-- New: transform tools -->
76
+ <div class="group">
77
+ <button part="flip-h" title="Flip horizontally">Flip H</button>
78
+ <button part="flip-v" title="Flip vertically">Flip V</button>
79
+ <button part="rot-ccw" title="Rotate -90°">⟲</button>
80
+ <button part="rot-cw" title="Rotate +90°">⟳</button>
81
+ </div>
82
+
83
+ <label
84
+ >opacity <input type="range" part="opacity" min="0" max="255" value="255" style="width:10rem" /><input
85
+ type="number"
86
+ part="opacity-num"
87
+ min="0"
88
+ max="255"
89
+ value="255"
90
+ style="width:5ch;margin-left:4px"
91
+ /></label>
92
+
93
+ <button part="clear" title="Clear (make fully transparent)">Clear</button>
94
+
53
95
  <button part="export">Export PNG</button>
54
96
  <button part="export-json">Export JSON</button>
55
97
  <button part="import-json">Import JSON</button>
@@ -79,11 +121,24 @@ class ObjectLayerEngineElement extends HTMLElement {
79
121
  this._importJsonBtn = this.shadowRoot.querySelector('button[part="import-json"]');
80
122
  this._toggleGrid = this.shadowRoot.querySelector('input[part="toggle-grid"]');
81
123
 
124
+ // new controls
125
+ this._widthInput = this.shadowRoot.querySelector('input[part="cell-width"]');
126
+ this._heightInput = this.shadowRoot.querySelector('input[part="cell-height"]');
127
+ this._flipHBtn = this.shadowRoot.querySelector('button[part="flip-h"]');
128
+ this._flipVBtn = this.shadowRoot.querySelector('button[part="flip-v"]');
129
+ this._rotCCWBtn = this.shadowRoot.querySelector('button[part="rot-ccw"]');
130
+ this._rotCWBtn = this.shadowRoot.querySelector('button[part="rot-cw"]');
131
+ this._clearBtn = this.shadowRoot.querySelector('button[part="clear"]');
132
+ this._opacityRange = this.shadowRoot.querySelector('input[part="opacity"]');
133
+ this._opacityNumber = this.shadowRoot.querySelector('input[part="opacity-num"]');
134
+
82
135
  // internal state
83
136
  this._width = 16;
84
137
  this._height = 16;
85
138
  this._pixelSize = 16;
86
139
  this._brushSize = 1;
140
+ // brush color stored as [r,g,b,a]
141
+ this._brushColor = [0, 0, 0, 255];
87
142
  this._matrix = this._createEmptyMatrix(this._width, this._height);
88
143
 
89
144
  this._pixelCtx = null;
@@ -91,13 +146,18 @@ class ObjectLayerEngineElement extends HTMLElement {
91
146
 
92
147
  this._isPointerDown = false;
93
148
  this._tool = 'pencil';
94
- this._brushColor = [0, 0, 0, 255];
95
149
  this._showGrid = false;
96
150
 
97
151
  // binds
98
152
  this._onPointerDown = this._onPointerDown.bind(this);
99
153
  this._onPointerMove = this._onPointerMove.bind(this);
100
154
  this._onPointerUp = this._onPointerUp.bind(this);
155
+
156
+ // transform methods bound (useful if passing as callbacks)
157
+ this.flipHorizontal = this.flipHorizontal.bind(this);
158
+ this.flipVertical = this.flipVertical.bind(this);
159
+ this.rotateCW = this.rotateCW.bind(this);
160
+ this.rotateCCW = this.rotateCCW.bind(this);
101
161
  }
102
162
 
103
163
  static get observedAttributes() {
@@ -111,16 +171,29 @@ class ObjectLayerEngineElement extends HTMLElement {
111
171
  }
112
172
 
113
173
  connectedCallback() {
174
+ // respect attributes if present
114
175
  if (this.hasAttribute('width')) this._width = Math.max(1, parseInt(this.getAttribute('width'), 10));
115
176
  if (this.hasAttribute('height')) this._height = Math.max(1, parseInt(this.getAttribute('height'), 10));
116
177
  if (this.hasAttribute('pixel-size')) this._pixelSize = Math.max(1, parseInt(this.getAttribute('pixel-size'), 10));
117
178
 
118
179
  this._setupContextsAndSize();
119
180
 
181
+ // set initial UI control values (keeps in sync with attributes)
182
+ if (this._widthInput) this._widthInput.value = String(this._width);
183
+ if (this._heightInput) this._heightInput.value = String(this._height);
184
+ if (this._pixelSizeInput) this._pixelSizeInput.value = String(this._pixelSize);
185
+ if (this._brushSizeInput) this._brushSizeInput.value = String(this._brushSize);
186
+
187
+ // initialize color & opacity UI
188
+ if (this._colorInput) this._colorInput.value = this._rgbaToHex(this._brushColor);
189
+ if (this._opacityRange) this._opacityRange.value = String(this._brushColor[3]);
190
+ if (this._opacityNumber) this._opacityNumber.value = String(this._brushColor[3]);
191
+
120
192
  // UI events
121
193
  this._colorInput.addEventListener('input', (e) => {
122
- const rgba = this._hexToRgba(e.target.value);
123
- this.setBrushColor([rgba[0], rgba[1], rgba[2], 255]);
194
+ const rgb = this._hexToRgba(e.target.value);
195
+ // keep current alpha
196
+ this.setBrushColor([rgb[0], rgb[1], rgb[2], this._brushColor[3]]);
124
197
  });
125
198
  this._toolSelect.addEventListener('change', (e) => this.setTool(e.target.value));
126
199
  this._brushSizeInput.addEventListener('change', (e) => this.setBrushSize(parseInt(e.target.value, 10) || 1));
@@ -132,6 +205,42 @@ class ObjectLayerEngineElement extends HTMLElement {
132
205
  this._renderGrid();
133
206
  });
134
207
 
208
+ // opacity controls - keep range and number in sync
209
+ if (this._opacityRange) {
210
+ this._opacityRange.addEventListener('input', (e) => {
211
+ const v = Math.max(0, Math.min(255, parseInt(e.target.value, 10) || 0));
212
+ this.setBrushAlpha(v);
213
+ });
214
+ }
215
+ if (this._opacityNumber) {
216
+ this._opacityNumber.addEventListener('change', (e) => {
217
+ const v = Math.max(0, Math.min(255, parseInt(e.target.value, 10) || 0));
218
+ this.setBrushAlpha(v);
219
+ });
220
+ }
221
+
222
+ // width/height change -> resize (preserve existing content)
223
+ if (this._widthInput)
224
+ this._widthInput.addEventListener('change', (e) => {
225
+ const val = Math.max(1, parseInt(e.target.value, 10) || 1);
226
+ // keep value synced (will update input again in resize)
227
+ this.resize(val, this._height, { preserve: true });
228
+ });
229
+ if (this._heightInput)
230
+ this._heightInput.addEventListener('change', (e) => {
231
+ const val = Math.max(1, parseInt(e.target.value, 10) || 1);
232
+ this.resize(this._width, val, { preserve: true });
233
+ });
234
+
235
+ // transform buttons
236
+ if (this._flipHBtn) this._flipHBtn.addEventListener('click', this.flipHorizontal);
237
+ if (this._flipVBtn) this._flipVBtn.addEventListener('click', this.flipVertical);
238
+ if (this._rotCWBtn) this._rotCWBtn.addEventListener('click', this.rotateCW);
239
+ if (this._rotCCWBtn) this._rotCCWBtn.addEventListener('click', this.rotateCCW);
240
+
241
+ // clear button (makes canvas fully transparent)
242
+ if (this._clearBtn) this._clearBtn.addEventListener('click', () => this.clear([0, 0, 0, 0]));
243
+
135
244
  // Export/Import
136
245
  this._exportBtn.addEventListener('click', () => this.exportPNG());
137
246
  this._exportJsonBtn.addEventListener('click', () => {
@@ -169,6 +278,14 @@ class ObjectLayerEngineElement extends HTMLElement {
169
278
  this._pixelCanvas.removeEventListener('pointerdown', this._onPointerDown);
170
279
  window.removeEventListener('pointermove', this._onPointerMove);
171
280
  window.removeEventListener('pointerup', this._onPointerUp);
281
+
282
+ if (this._flipHBtn) this._flipHBtn.removeEventListener('click', this.flipHorizontal);
283
+ if (this._flipVBtn) this._flipVBtn.removeEventListener('click', this.flipVertical);
284
+ if (this._rotCWBtn) this._rotCWBtn.removeEventListener('click', this.rotateCW);
285
+ if (this._rotCCWBtn) this._rotCCWBtn.removeEventListener('click', this.rotateCCW);
286
+ if (this._clearBtn) this._clearBtn.removeEventListener('click', () => this.clear([0, 0, 0, 0]));
287
+ if (this._opacityRange) this._opacityRange.removeEventListener('input', () => {});
288
+ if (this._opacityNumber) this._opacityNumber.removeEventListener('change', () => {});
172
289
  }
173
290
 
174
291
  // ---------------- Matrix helpers ----------------
@@ -227,6 +344,13 @@ class ObjectLayerEngineElement extends HTMLElement {
227
344
  this._width = nw;
228
345
  this._height = nh;
229
346
  this._matrix = newMat;
347
+
348
+ // keep inputs and attributes in sync
349
+ if (this._widthInput) this._widthInput.value = String(this._width);
350
+ if (this._heightInput) this._heightInput.value = String(this._height);
351
+ this.setAttribute('width', String(this._width));
352
+ this.setAttribute('height', String(this._height));
353
+
230
354
  this._setupContextsAndSize();
231
355
  this.render();
232
356
  this.dispatchEvent(new CustomEvent('resize', { detail: { width: nw, height: nh } }));
@@ -365,10 +489,33 @@ class ObjectLayerEngineElement extends HTMLElement {
365
489
  this._tool = name;
366
490
  if (this._toolSelect) this._toolSelect.value = name;
367
491
  }
492
+
493
+ // set full RGBA brush color (alpha optional)
368
494
  setBrushColor(rgba) {
369
- this._brushColor = rgba.map((n) => this._clampInt(n));
495
+ if (!Array.isArray(rgba) || rgba.length < 3) return;
496
+ const r = this._clampInt(rgba[0]);
497
+ const g = this._clampInt(rgba[1]);
498
+ const b = this._clampInt(rgba[2]);
499
+ const a = typeof rgba[3] === 'number' ? this._clampInt(rgba[3]) : this._brushColor[3];
500
+ this._brushColor = [r, g, b, a];
370
501
  if (this._colorInput) this._colorInput.value = this._rgbaToHex(this._brushColor);
502
+ if (this._opacityRange) this._opacityRange.value = String(this._brushColor[3]);
503
+ if (this._opacityNumber) this._opacityNumber.value = String(this._brushColor[3]);
371
504
  }
505
+
506
+ // set brush alpha (0-255)
507
+ setBrushAlpha(a) {
508
+ const v = Math.max(0, Math.min(255, Math.floor(Number(a) || 0)));
509
+ this._brushColor[3] = v;
510
+ if (this._opacityRange) this._opacityRange.value = String(v);
511
+ if (this._opacityNumber) this._opacityNumber.value = String(v);
512
+ // keep color input (hex) representing rgb only
513
+ if (this._colorInput) this._colorInput.value = this._rgbaToHex(this._brushColor);
514
+ }
515
+ getBrushAlpha() {
516
+ return this._brushColor[3];
517
+ }
518
+
372
519
  setBrushSize(n) {
373
520
  this._brushSize = Math.max(1, Math.floor(n));
374
521
  if (this._brushSizeInput) this._brushSizeInput.value = this._brushSize;
@@ -584,6 +731,84 @@ class ObjectLayerEngineElement extends HTMLElement {
584
731
  .slice(1)}`;
585
732
  }
586
733
 
734
+ // ---------------- Transform helpers (flip/rotate) ----------------
735
+ flipHorizontal() {
736
+ // reverse each row (mirror horizontally)
737
+ for (let y = 0; y < this._height; y++) {
738
+ this._matrix[y].reverse();
739
+ }
740
+ this.render();
741
+ this.dispatchEvent(new CustomEvent('transform', { detail: { type: 'flip-horizontal' } }));
742
+ }
743
+
744
+ flipVertical() {
745
+ // reverse the order of rows (mirror vertically)
746
+ this._matrix.reverse();
747
+ this.render();
748
+ this.dispatchEvent(new CustomEvent('transform', { detail: { type: 'flip-vertical' } }));
749
+ }
750
+
751
+ rotateCW() {
752
+ // rotate +90 degrees (clockwise)
753
+ const oldH = this._height;
754
+ const oldW = this._width;
755
+ const newW = oldH;
756
+ const newH = oldW;
757
+ const newMat = this._createEmptyMatrix(newW, newH);
758
+ for (let y = 0; y < oldH; y++) {
759
+ for (let x = 0; x < oldW; x++) {
760
+ const px = this._matrix[y][x] ? this._matrix[y][x].slice() : [0, 0, 0, 0];
761
+ const newX = oldH - 1 - y; // column in new matrix
762
+ const newY = x; // row in new matrix
763
+ newMat[newY][newX] = px;
764
+ }
765
+ }
766
+ this._width = newW;
767
+ this._height = newH;
768
+ this._matrix = newMat;
769
+ // keep inputs/attributes in sync
770
+ if (this._widthInput) this._widthInput.value = String(this._width);
771
+ if (this._heightInput) this._heightInput.value = String(this._height);
772
+ this.setAttribute('width', String(this._width));
773
+ this.setAttribute('height', String(this._height));
774
+
775
+ this._setupContextsAndSize();
776
+ this.render();
777
+ this.dispatchEvent(
778
+ new CustomEvent('transform', { detail: { type: 'rotate-cw', width: this._width, height: this._height } }),
779
+ );
780
+ }
781
+
782
+ rotateCCW() {
783
+ // rotate -90 degrees (counter-clockwise)
784
+ const oldH = this._height;
785
+ const oldW = this._width;
786
+ const newW = oldH;
787
+ const newH = oldW;
788
+ const newMat = this._createEmptyMatrix(newW, newH);
789
+ for (let y = 0; y < oldH; y++) {
790
+ for (let x = 0; x < oldW; x++) {
791
+ const px = this._matrix[y][x] ? this._matrix[y][x].slice() : [0, 0, 0, 0];
792
+ const newX = y; // column in new matrix
793
+ const newY = oldW - 1 - x; // row in new matrix
794
+ newMat[newY][newX] = px;
795
+ }
796
+ }
797
+ this._width = newW;
798
+ this._height = newH;
799
+ this._matrix = newMat;
800
+ if (this._widthInput) this._widthInput.value = String(this._width);
801
+ if (this._heightInput) this._heightInput.value = String(this._height);
802
+ this.setAttribute('width', String(this._width));
803
+ this.setAttribute('height', String(this._height));
804
+
805
+ this._setupContextsAndSize();
806
+ this.render();
807
+ this.dispatchEvent(
808
+ new CustomEvent('transform', { detail: { type: 'rotate-ccw', width: this._width, height: this._height } }),
809
+ );
810
+ }
811
+
587
812
  // ---------------- Properties ----------------
588
813
  get width() {
589
814
  return this._width;