vanilla-jui 1.6.5 → 1.7.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-jui",
3
- "version": "1.6.5",
3
+ "version": "1.7.0",
4
4
  "private": false,
5
5
  "description": "A lightweight, reactive, and fully customizable vanilla JS UI library.",
6
6
  "keywords": [
@@ -136,11 +136,22 @@
136
136
  var(--ui-bg-muted) 0%,
137
137
  var(--ui-surface-subtle) 100%
138
138
  );
139
+ color: var(--ui-fg-subtle);
140
+ font-size: var(--font-size-sm);
139
141
  display: flex;
140
142
  align-items: center;
141
143
  justify-content: center;
142
- color: var(--ui-fg-subtle);
143
- font-size: var(--font-size-sm);
144
+ }
145
+
146
+ /* 图片容器 */
147
+ .image-container {
148
+ position: relative;
149
+ }
150
+
151
+ .image-container img {
152
+ position: absolute;
153
+ width: 100%;
154
+ height: 100%;
144
155
  }
145
156
 
146
157
  /* ==============================
@@ -43,7 +43,7 @@
43
43
  border-radius: var(--menu-item-border-radius);
44
44
  }
45
45
 
46
- .j-menu>.menu>.menu-item>a {
46
+ .j-menu > .menu > .menu-item > a {
47
47
  font-weight: var(--font-medium);
48
48
  }
49
49
 
@@ -53,7 +53,7 @@
53
53
  height: var(--menu-item-icon-size);
54
54
  }
55
55
 
56
- .j-menu .menu .menu-item.menu-item-has-children>a::after {
56
+ .j-menu .menu .menu-item.menu-item-has-children > a::after {
57
57
  content: '';
58
58
  width: 0;
59
59
  height: 0;
@@ -65,12 +65,12 @@
65
65
  transition: transform 0.2s ease-in-out;
66
66
  }
67
67
 
68
- .j-menu .menu .menu-item.menu-item-has-children:hover>a::after {
68
+ .j-menu .menu .menu-item.menu-item-has-children:hover > a::after {
69
69
  transform: rotate(180deg);
70
70
  }
71
71
 
72
72
  .j-menu .menu .menu-item .sub-menu {
73
- transform: translateY(1px);
73
+ /* transform: translateY(1px); */
74
74
  padding: var(--s2) 0;
75
75
  background: var(--sub-menu-bg);
76
76
  border-width: var(--sub-menu-border-width);
@@ -99,26 +99,39 @@
99
99
 
100
100
  .j-menu .menu .menu-item .sub-menu .menu-item:hover a,
101
101
  .j-menu .menu .menu-item a:hover,
102
- .j-menu .menu .menu-item.menu-item-has-children:hover>a {
102
+ .j-menu .menu .menu-item.menu-item-has-children:hover > a {
103
103
  text-decoration: none;
104
104
  background: var(--tone-soft);
105
105
  color: var(--tone-text);
106
106
  }
107
107
 
108
- .j-menu .menu>.menu-item.current-menu-item>a,
109
- .j-menu .menu>.menu-item.current-menu-ancestor>a {
108
+ .j-menu .menu > .menu-item.current-menu-item > a,
109
+ .j-menu .menu > .menu-item.current-menu-ancestor > a {
110
110
  color: var(--tone-solid);
111
111
  }
112
112
 
113
- .j-menu .menu .menu-item.current-menu-item>.sub-menu>.menu-item:not(.current-menu-item) a {
113
+ .j-menu
114
+ .menu
115
+ .menu-item.current-menu-item
116
+ > .sub-menu
117
+ > .menu-item:not(.current-menu-item)
118
+ a {
114
119
  color: inherit;
115
120
  }
116
121
 
117
- .j-menu .menu-item.current-menu-item>.sub-menu>.menu-item:not(.current-menu-item):hover a {
122
+ .j-menu
123
+ .menu-item.current-menu-item
124
+ > .sub-menu
125
+ > .menu-item:not(.current-menu-item):hover
126
+ a {
118
127
  color: var(--tone-fg);
119
128
  }
120
129
 
121
- .j-menu .menu-item.menu-item-has-children:hover>.sub-menu>.menu-item.current-menu-item a {
130
+ .j-menu
131
+ .menu-item.menu-item-has-children:hover
132
+ > .sub-menu
133
+ > .menu-item.current-menu-item
134
+ a {
122
135
  color: var(--tone-fg);
123
136
  background-color: var(--tone-solid);
124
137
  outline: 1px solid var(--tone-solid);
@@ -144,13 +157,13 @@
144
157
  }
145
158
 
146
159
  /* list card menu */
147
- .j-menu .menu-item.menu-item-has-children.list-card-menu:hover>.sub-menu {
160
+ .j-menu .menu-item.menu-item-has-children.list-card-menu:hover > .sub-menu {
148
161
  width: auto;
149
162
  display: grid;
150
163
  grid-template-columns: repeat(2, 1fr);
151
164
  }
152
165
 
153
- .j-menu .menu-item.list-card-menu>.sub-menu>.menu-item>a {
166
+ .j-menu .menu-item.list-card-menu > .sub-menu > .menu-item > a {
154
167
  overflow: hidden;
155
168
  display: -webkit-box;
156
169
  -webkit-box-orient: vertical;
@@ -158,19 +171,21 @@
158
171
  line-clamp: 1;
159
172
  }
160
173
 
161
- .j-menu .menu-item.menu-item-has-children.list-card-menu:hover>.sub-menu {
174
+ .j-menu .menu-item.menu-item-has-children.list-card-menu:hover > .sub-menu {
162
175
  min-width: 240px;
163
176
  max-width: 360px;
164
177
  transform: translateX(-20%) translateY(1px);
165
178
  }
166
179
 
167
- .j-menu .menu-item.list-card-menu>.sub-menu>.menu-item>a {
180
+ .j-menu .menu-item.list-card-menu > .sub-menu > .menu-item > a {
168
181
  padding: calc(var(--space) * 1.25) calc(var(--space) * 2.5);
169
182
  line-height: 1.75;
170
183
  }
171
184
 
172
185
  /* advanced card menu */
173
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu {
186
+ .j-menu
187
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
188
+ > .sub-menu {
174
189
  display: grid;
175
190
  grid-template-columns: repeat(6, 1fr);
176
191
  grid-template-rows: repeat(6, 1fr);
@@ -182,61 +197,126 @@
182
197
  transform: translateX(-33.33%) translateY(1px);
183
198
  }
184
199
 
185
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu img {
200
+ .j-menu
201
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
202
+ > .sub-menu
203
+ img {
186
204
  margin: 0;
187
205
  }
188
206
 
189
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(1) {
207
+ .j-menu
208
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
209
+ > .sub-menu
210
+ > .menu-item:nth-child(1) {
190
211
  grid-area: 1 / 1 / 2 / 3;
191
212
  }
192
213
 
193
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(2) {
214
+ .j-menu
215
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
216
+ > .sub-menu
217
+ > .menu-item:nth-child(2) {
194
218
  grid-area: 1 / 3 / 4 / 5;
195
219
  }
196
220
 
197
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(3) {
221
+ .j-menu
222
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
223
+ > .sub-menu
224
+ > .menu-item:nth-child(3) {
198
225
  grid-area: 1 / 5 / 4 / 7;
199
226
  }
200
227
 
201
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(4) {
228
+ .j-menu
229
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
230
+ > .sub-menu
231
+ > .menu-item:nth-child(4) {
202
232
  grid-area: 2 / 1 / 3 / 3;
203
233
  }
204
234
 
205
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(5) {
235
+ .j-menu
236
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
237
+ > .sub-menu
238
+ > .menu-item:nth-child(5) {
206
239
  grid-area: 3 / 1 / 4 / 3;
207
240
  }
208
241
 
209
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(6) {
242
+ .j-menu
243
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
244
+ > .sub-menu
245
+ > .menu-item:nth-child(6) {
210
246
  grid-area: 4 / 1 / 5 / 3;
211
247
  }
212
248
 
213
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(7) {
249
+ .j-menu
250
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
251
+ > .sub-menu
252
+ > .menu-item:nth-child(7) {
214
253
  grid-area: 4 / 3 / 7 / 5;
215
254
  }
216
255
 
217
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(8) {
256
+ .j-menu
257
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
258
+ > .sub-menu
259
+ > .menu-item:nth-child(8) {
218
260
  grid-area: 4 / 5 / 7 / 7;
219
261
  }
220
262
 
221
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(9) {
263
+ .j-menu
264
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
265
+ > .sub-menu
266
+ > .menu-item:nth-child(9) {
222
267
  grid-area: 5 / 1 / 6 / 3;
223
268
  }
224
269
 
225
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(10) {
270
+ .j-menu
271
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
272
+ > .sub-menu
273
+ > .menu-item:nth-child(10) {
226
274
  grid-area: 6 / 1 / 7 / 3;
227
275
  }
228
276
 
229
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(2) a,
230
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(3) a,
231
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(7) a,
232
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(8) a {
277
+ .j-menu
278
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
279
+ > .sub-menu
280
+ > .menu-item:nth-child(2)
281
+ a,
282
+ .j-menu
283
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
284
+ > .sub-menu
285
+ > .menu-item:nth-child(3)
286
+ a,
287
+ .j-menu
288
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
289
+ > .sub-menu
290
+ > .menu-item:nth-child(7)
291
+ a,
292
+ .j-menu
293
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
294
+ > .sub-menu
295
+ > .menu-item:nth-child(8)
296
+ a {
233
297
  padding: 0;
234
298
  }
235
299
 
236
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(2) a:hover,
237
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(3) a:hover,
238
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(7) a:hover,
239
- .j-menu .menu-item.menu-item-has-children.advanced-card-menu:hover>.sub-menu>.menu-item:nth-child(8) a:hover {
300
+ .j-menu
301
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
302
+ > .sub-menu
303
+ > .menu-item:nth-child(2)
304
+ a:hover,
305
+ .j-menu
306
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
307
+ > .sub-menu
308
+ > .menu-item:nth-child(3)
309
+ a:hover,
310
+ .j-menu
311
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
312
+ > .sub-menu
313
+ > .menu-item:nth-child(7)
314
+ a:hover,
315
+ .j-menu
316
+ .menu-item.menu-item-has-children.advanced-card-menu:hover
317
+ > .sub-menu
318
+ > .menu-item:nth-child(8)
319
+ a:hover {
240
320
  background-color: transparent;
241
321
  outline-color: transparent;
242
322
  }
@@ -288,7 +368,10 @@
288
368
  line-height: var(--line-height-paragraph);
289
369
  }
290
370
 
291
- .j-menu[data-menu-type='mobile'] .menu .menu-item.menu-item-has-children>a::after {
371
+ .j-menu[data-menu-type='mobile']
372
+ .menu
373
+ .menu-item.menu-item-has-children
374
+ > a::after {
292
375
  vertical-align: middle;
293
376
  position: absolute;
294
377
  right: 1rem;
@@ -298,7 +381,10 @@
298
381
  border-top: 4px solid transparent;
299
382
  }
300
383
 
301
- .j-menu[data-menu-type='mobile'] .menu .menu-item.menu-item-has-children:hover>a::after {
384
+ .j-menu[data-menu-type='mobile']
385
+ .menu
386
+ .menu-item.menu-item-has-children:hover
387
+ > a::after {
302
388
  transform: none;
303
389
  }
304
390
 
@@ -316,7 +402,10 @@
316
402
  }
317
403
 
318
404
  .j-menu[data-menu-type='mobile'] .menu .menu-item a:hover,
319
- .j-menu[data-menu-type='mobile'] .menu .menu-item.menu-item-has-children:hover>a,
405
+ .j-menu[data-menu-type='mobile']
406
+ .menu
407
+ .menu-item.menu-item-has-children:hover
408
+ > a,
320
409
  .j-menu[data-menu-type='mobile'] .menu .sub-menu .menu-item:hover a {
321
410
  background: inherit;
322
411
  color: inherit;
@@ -326,7 +415,10 @@
326
415
  background: var(--menu-item-active-bg);
327
416
  }
328
417
 
329
- .j-menu[data-menu-type='mobile'] .menu .menu-item.menu-item-has-children.is-active>.sub-menu {
418
+ .j-menu[data-menu-type='mobile']
419
+ .menu
420
+ .menu-item.menu-item-has-children.is-active
421
+ > .sub-menu {
330
422
  visibility: visible;
331
423
  opacity: 1;
332
424
  z-index: var(--z-submenu);
@@ -338,12 +430,14 @@
338
430
  */
339
431
  .j-menu[data-menu-type='bottom'] {
340
432
  --menu-item-border-radius: none;
341
- --sub-menu-bg: linear-gradient(to right,
342
- var(--ui-surface-subtle) 20%,
343
- var(--ui-border) 40%,
344
- var(--ui-outline) 50%,
345
- var(--ui-border) 60%,
346
- var(--ui-surface-subtle) 80%);
433
+ --sub-menu-bg: linear-gradient(
434
+ to right,
435
+ var(--ui-surface-subtle) 20%,
436
+ var(--ui-border) 40%,
437
+ var(--ui-outline) 50%,
438
+ var(--ui-border) 60%,
439
+ var(--ui-surface-subtle) 80%
440
+ );
347
441
 
348
442
  position: fixed;
349
443
  bottom: 0;
@@ -358,12 +452,14 @@
358
452
  justify-content: space-between;
359
453
  gap: 1px;
360
454
  border-top: 1px solid var(--ui-border-subtle);
361
- background: linear-gradient(to bottom,
362
- var(--ui-bg-subtle) 20%,
363
- var(--ui-border) 40%,
364
- var(--ui-outline) 50%,
365
- var(--ui-border) 60%,
366
- var(--ui-bg-subtle) 80%);
455
+ background: linear-gradient(
456
+ to bottom,
457
+ var(--ui-bg-subtle) 20%,
458
+ var(--ui-border) 40%,
459
+ var(--ui-outline) 50%,
460
+ var(--ui-border) 60%,
461
+ var(--ui-bg-subtle) 80%
462
+ );
367
463
  }
368
464
 
369
465
  .j-menu[data-menu-type='bottom'] .menu .menu-item {
@@ -381,7 +477,10 @@
381
477
  color: var(--ui-fg);
382
478
  }
383
479
 
384
- .j-menu[data-menu-type='bottom']>.menu>.menu-item.menu-item-has-children>a::after {
480
+ .j-menu[data-menu-type='bottom']
481
+ > .menu
482
+ > .menu-item.menu-item-has-children
483
+ > a::after {
385
484
  content: '☰';
386
485
  font-size: var(--font-size-sm);
387
486
  margin-left: unset;
@@ -391,17 +490,26 @@
391
490
  transition: unset;
392
491
  }
393
492
 
394
- .j-menu[data-menu-type='bottom']>.menu .menu-item.menu-item-has-children:hover>a::after {
493
+ .j-menu[data-menu-type='bottom']
494
+ > .menu
495
+ .menu-item.menu-item-has-children:hover
496
+ > a::after {
395
497
  transform: none;
396
498
  }
397
499
 
398
- .j-menu[data-menu-type='bottom'] .menu .menu-item.current-menu-parent>a,
399
- .j-menu[data-menu-type='bottom'] .menu .menu-item.current-menu-item>a,
400
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children.is-active>a {
500
+ .j-menu[data-menu-type='bottom'] .menu .menu-item.current-menu-parent > a,
501
+ .j-menu[data-menu-type='bottom'] .menu .menu-item.current-menu-item > a,
502
+ .j-menu[data-menu-type='bottom']
503
+ .menu
504
+ .menu-item.menu-item-has-children.is-active
505
+ > a {
401
506
  color: var(--tone-solid);
402
507
  }
403
508
 
404
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children>.sub-menu {
509
+ .j-menu[data-menu-type='bottom']
510
+ .menu
511
+ .menu-item.menu-item-has-children
512
+ > .sub-menu {
405
513
  opacity: 0;
406
514
  visibility: hidden;
407
515
  display: flex;
@@ -423,28 +531,48 @@
423
531
  z-index: -1;
424
532
  }
425
533
 
426
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children.is-active>.sub-menu {
534
+ .j-menu[data-menu-type='bottom']
535
+ .menu
536
+ .menu-item.menu-item-has-children.is-active
537
+ > .sub-menu {
427
538
  opacity: 1;
428
539
  visibility: visible;
429
540
  transform: translateX(-50%) translateY(0%);
430
541
  }
431
542
 
432
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children>.sub-menu>.menu-item {
543
+ .j-menu[data-menu-type='bottom']
544
+ .menu
545
+ .menu-item.menu-item-has-children
546
+ > .sub-menu
547
+ > .menu-item {
433
548
  white-space: normal;
434
549
  border: 1px solid transparent;
435
550
  }
436
551
 
437
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children>.sub-menu>.menu-item>a {
552
+ .j-menu[data-menu-type='bottom']
553
+ .menu
554
+ .menu-item.menu-item-has-children
555
+ > .sub-menu
556
+ > .menu-item
557
+ > a {
438
558
  min-height: var(--el-height-2xl);
439
559
  justify-content: center;
440
560
  }
441
561
 
442
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children>.sub-menu>.menu-item:first-of-type {
562
+ .j-menu[data-menu-type='bottom']
563
+ .menu
564
+ .menu-item.menu-item-has-children
565
+ > .sub-menu
566
+ > .menu-item:first-of-type {
443
567
  border-top-left-radius: var(--radius-md);
444
568
  border-top-right-radius: var(--radius-md);
445
569
  }
446
570
 
447
- .j-menu[data-menu-type='bottom'] .menu .menu-item.menu-item-has-children>.sub-menu>.menu-item:last-of-type {
571
+ .j-menu[data-menu-type='bottom']
572
+ .menu
573
+ .menu-item.menu-item-has-children
574
+ > .sub-menu
575
+ > .menu-item:last-of-type {
448
576
  border-bottom-left-radius: var(--radius-md);
449
577
  border-bottom-right-radius: var(--radius-md);
450
578
  }
@@ -515,4 +643,4 @@
515
643
  color: var(--ui-fg-soft);
516
644
  font-size: var(--font-size-sm);
517
645
  }
518
- }
646
+ }
@@ -55,3 +55,76 @@ export function randomId(length: number = 8): string {
55
55
 
56
56
  return base64.substring(0, length).replace(/\+/g, '-').replace(/\//g, '_');
57
57
  }
58
+
59
+ /**
60
+ * 查询参数值类型
61
+ */
62
+ type QueryParamValue =
63
+ | string
64
+ | number
65
+ | boolean
66
+ | null
67
+ | undefined
68
+ | QueryParamValue[]
69
+ | { [key: string]: QueryParamValue };
70
+
71
+ /**
72
+ * 查询参数对象类型
73
+ */
74
+ type QueryParams = Record<string, QueryParamValue>;
75
+
76
+ /**
77
+ * 对查询参数进行 SHA-256 哈希编码,生成用于缓存的 key
78
+ *
79
+ * @param params - 查询参数对象
80
+ * @param bytes - 取哈希前 N 字节,默认为 8,范围 1-32
81
+ * @returns 36 进制哈希字符串
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const key = await hashQueryParams({ page: 1, sort: 'desc' });
86
+ * // 返回: "2k7x9f3m4n5p"
87
+ * ```
88
+ */
89
+ export async function hashQueryParams(
90
+ params: QueryParams,
91
+ bytes: number = 8
92
+ ): Promise<string> {
93
+ // 1. 参数验证
94
+ if (typeof params !== 'object' || params === null) {
95
+ throw new TypeError('params must be a non-null object');
96
+ }
97
+
98
+ if (bytes < 1 || bytes > 32) {
99
+ throw new RangeError('bytes must be between 1 and 32');
100
+ }
101
+
102
+ // 2. 排序并规范化参数
103
+ const normalized: QueryParams = {};
104
+ const sortedKeys = Object.keys(params).sort();
105
+
106
+ for (const key of sortedKeys) {
107
+ const value = params[key];
108
+ // 字符串 trim 处理
109
+ normalized[key] = typeof value === 'string' ? value.trim() : value;
110
+ }
111
+
112
+ // 3. 序列化
113
+ const str = JSON.stringify(normalized);
114
+ const buffer = new TextEncoder().encode(str);
115
+
116
+ // 4. SHA-256 哈希
117
+ const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
118
+
119
+ // 5. 取前 N 字节(防越界)
120
+ const safeBytes = Math.min(bytes, hashBuffer.byteLength);
121
+ const slice = new Uint8Array(hashBuffer, 0, safeBytes);
122
+
123
+ // 6. 转为 BigInt 再转 36 进制
124
+ let num = 0n;
125
+ for (const byte of slice) {
126
+ num = (num << 8n) | BigInt(byte);
127
+ }
128
+
129
+ return num.toString(36);
130
+ }