xiv-strat-board 0.1.2 → 0.2.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/README.md +5 -5
- package/dist/index.cjs +89 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +89 -65
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -365,24 +365,6 @@ var BOARD_BACKGROUND_IDS = {
|
|
|
365
365
|
grey_circle: 6,
|
|
366
366
|
grey_square: 7
|
|
367
367
|
};
|
|
368
|
-
var OBJECT_BACKGROUND_TYPES = {
|
|
369
|
-
0: "none",
|
|
370
|
-
1: "checkered",
|
|
371
|
-
2: "checkered_circle",
|
|
372
|
-
3: "checkered_square",
|
|
373
|
-
4: "grey",
|
|
374
|
-
5: "grey_circle",
|
|
375
|
-
6: "grey_square"
|
|
376
|
-
};
|
|
377
|
-
var OBJECT_BACKGROUND_IDS = {
|
|
378
|
-
none: 0,
|
|
379
|
-
checkered: 1,
|
|
380
|
-
checkered_circle: 2,
|
|
381
|
-
checkered_square: 3,
|
|
382
|
-
grey: 4,
|
|
383
|
-
grey_circle: 5,
|
|
384
|
-
grey_square: 6
|
|
385
|
-
};
|
|
386
368
|
|
|
387
369
|
// src/validation.ts
|
|
388
370
|
var BOUNDS = {
|
|
@@ -395,9 +377,9 @@ var BOUNDS = {
|
|
|
395
377
|
/** Maximum Y coordinate */
|
|
396
378
|
maxY: 484,
|
|
397
379
|
/** Minimum size percentage */
|
|
398
|
-
minSize:
|
|
380
|
+
minSize: 10,
|
|
399
381
|
/** Maximum size percentage */
|
|
400
|
-
maxSize:
|
|
382
|
+
maxSize: 200,
|
|
401
383
|
/** Minimum arc angle */
|
|
402
384
|
minArc: 0,
|
|
403
385
|
/** Maximum arc angle */
|
|
@@ -408,8 +390,10 @@ var BOUNDS = {
|
|
|
408
390
|
maxDonut: 255,
|
|
409
391
|
/** Maximum number of objects per board */
|
|
410
392
|
maxObjects: 50,
|
|
393
|
+
/** Maximum number of text objects per board */
|
|
394
|
+
maxTextObjects: 8,
|
|
411
395
|
/** Maximum name length (bytes) */
|
|
412
|
-
maxNameLength:
|
|
396
|
+
maxNameLength: 20
|
|
413
397
|
};
|
|
414
398
|
var VALID_CIPHER_CHARS = new Set(
|
|
415
399
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-_".split("")
|
|
@@ -484,19 +468,6 @@ function parseHexColor(color) {
|
|
|
484
468
|
b: parseInt(hex.slice(4, 6), 16)
|
|
485
469
|
};
|
|
486
470
|
}
|
|
487
|
-
function validateBackground(value) {
|
|
488
|
-
if (typeof value === "number") {
|
|
489
|
-
if (value >= 0 && value <= 6) {
|
|
490
|
-
return value;
|
|
491
|
-
}
|
|
492
|
-
return 0;
|
|
493
|
-
}
|
|
494
|
-
if (typeof value === "string") {
|
|
495
|
-
const id = OBJECT_BACKGROUND_IDS[value.toLowerCase()];
|
|
496
|
-
return id ?? 0;
|
|
497
|
-
}
|
|
498
|
-
return 0;
|
|
499
|
-
}
|
|
500
471
|
function validateBoardBackground(value) {
|
|
501
472
|
if (typeof value === "string") {
|
|
502
473
|
const id = BOARD_BACKGROUND_IDS[value.toLowerCase()];
|
|
@@ -547,16 +518,26 @@ function sanitizeObject(obj, index) {
|
|
|
547
518
|
typeId,
|
|
548
519
|
x: sanitizeCoordinate(obj.x, true),
|
|
549
520
|
y: sanitizeCoordinate(obj.y, false),
|
|
550
|
-
size: sanitizeSize(obj.size),
|
|
551
|
-
|
|
521
|
+
size: typeId === 100 ? 100 : sanitizeSize(obj.size),
|
|
522
|
+
angle: Math.round(obj.angle ?? 0),
|
|
552
523
|
colorR: sanitizeColorComponent(colorR),
|
|
553
524
|
colorG: sanitizeColorComponent(colorG),
|
|
554
525
|
colorB: sanitizeColorComponent(colorB),
|
|
555
526
|
transparency: sanitizeColorComponent(obj.transparency ?? 0),
|
|
556
|
-
arcAngle: clamp(Math.round(obj.arcAngle ?? 0), BOUNDS.minArc, BOUNDS.maxArc),
|
|
527
|
+
arcAngle: clamp(Math.round((obj.arcAngle ?? 0) / 10) * 10, BOUNDS.minArc, BOUNDS.maxArc),
|
|
557
528
|
donutRadius: clamp(Math.round(obj.donutRadius ?? 0), BOUNDS.minDonut, BOUNDS.maxDonut),
|
|
529
|
+
width: Math.round(obj.width ?? 0),
|
|
530
|
+
height: Math.round(obj.height ?? 0),
|
|
531
|
+
endX: sanitizeCoordinate(obj.endX ?? 0, true),
|
|
532
|
+
endY: sanitizeCoordinate(obj.endY ?? 0, false),
|
|
533
|
+
displayCount: Math.round(obj.displayCount ?? 0),
|
|
534
|
+
horizontalCount: Math.round(obj.horizontalCount ?? 0),
|
|
535
|
+
verticalCount: Math.round(obj.verticalCount ?? 0),
|
|
536
|
+
text: typeof obj.text === "string" ? obj.text.slice(0, 30) : "",
|
|
558
537
|
hidden: Boolean(obj.hidden),
|
|
559
|
-
locked: Boolean(obj.locked)
|
|
538
|
+
locked: Boolean(obj.locked),
|
|
539
|
+
horizontalFlip: Boolean(obj.horizontalFlip),
|
|
540
|
+
verticalFlip: Boolean(obj.verticalFlip)
|
|
560
541
|
};
|
|
561
542
|
}
|
|
562
543
|
function sanitizeBoard(board) {
|
|
@@ -569,6 +550,10 @@ function sanitizeBoard(board) {
|
|
|
569
550
|
if (board.objects.length > BOUNDS.maxObjects) {
|
|
570
551
|
throw new Error(`Board has too many objects (max ${BOUNDS.maxObjects})`);
|
|
571
552
|
}
|
|
553
|
+
const textCount = board.objects.filter((obj) => obj.type === "text" || obj.typeId === 100).length;
|
|
554
|
+
if (textCount > BOUNDS.maxTextObjects) {
|
|
555
|
+
throw new Error(`Board has too many text objects (max ${BOUNDS.maxTextObjects})`);
|
|
556
|
+
}
|
|
572
557
|
return {
|
|
573
558
|
name: sanitizeName(board.name),
|
|
574
559
|
boardBackground: validateBoardBackground(board.boardBackground),
|
|
@@ -792,15 +777,9 @@ function parseBinary(data) {
|
|
|
792
777
|
x: positions[i]?.x ?? 0,
|
|
793
778
|
y: positions[i]?.y ?? 0
|
|
794
779
|
};
|
|
795
|
-
obj.size = sizes[i] && sizes[i] > 0 ? sizes[i] : 100;
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
if (backgrounds[i] !== void 0 && backgrounds[i] !== 0) {
|
|
799
|
-
obj.angle = backgrounds[i];
|
|
800
|
-
}
|
|
801
|
-
} else if (backgrounds[i] !== void 0 && backgrounds[i] > 0) {
|
|
802
|
-
const bgName = OBJECT_BACKGROUND_TYPES[backgrounds[i]];
|
|
803
|
-
obj.background = bgName ?? backgrounds[i];
|
|
780
|
+
obj.size = iconId === 100 ? 100 : sizes[i] && sizes[i] > 0 ? sizes[i] : 100;
|
|
781
|
+
if (iconId !== 100 && backgrounds[i] !== void 0 && backgrounds[i] !== 0) {
|
|
782
|
+
obj.angle = backgrounds[i];
|
|
804
783
|
}
|
|
805
784
|
const colorableTypes = /* @__PURE__ */ new Set([11, 12, 100]);
|
|
806
785
|
if (colors[i]) {
|
|
@@ -846,10 +825,10 @@ function parseBinary(data) {
|
|
|
846
825
|
obj.verticalCount = tag11[i];
|
|
847
826
|
}
|
|
848
827
|
} else if (iconId === 17) {
|
|
849
|
-
if (tag10[i] && tag10[i] > 0) {
|
|
828
|
+
if (tag10[i] !== void 0 && tag10[i] > 0) {
|
|
850
829
|
obj.arcAngle = tag10[i];
|
|
851
830
|
}
|
|
852
|
-
if (tag11[i]
|
|
831
|
+
if (tag11[i] !== void 0) {
|
|
853
832
|
obj.donutRadius = tag11[i];
|
|
854
833
|
}
|
|
855
834
|
} else {
|
|
@@ -888,9 +867,20 @@ function parseBinary(data) {
|
|
|
888
867
|
function buildBinary(data) {
|
|
889
868
|
const { name, boardBackground, objects } = data;
|
|
890
869
|
const n = objects.length;
|
|
870
|
+
const nameBytes = new TextEncoder().encode(name.slice(0, 20));
|
|
871
|
+
const namePaddedLen = Math.max(8, nameBytes.length + 1 + 3 & -4);
|
|
872
|
+
const headerSize = 28 + namePaddedLen;
|
|
891
873
|
const tag4Size = n <= 1 ? 8 : 6 + n * 2;
|
|
892
874
|
const tag7Size = 6 + n + (n % 2 === 1 ? 1 : 0);
|
|
893
|
-
|
|
875
|
+
let textContentSize = 0;
|
|
876
|
+
for (const obj of objects) {
|
|
877
|
+
if (obj.typeId === 100 && obj.text) {
|
|
878
|
+
const textLen = new TextEncoder().encode(obj.text).length;
|
|
879
|
+
const paddedLen = Math.max(8, textLen + 1 + 3 & -4);
|
|
880
|
+
textContentSize += 4 + paddedLen;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
const bufferSize = n === 0 ? headerSize + 8 : headerSize + n * 4 + textContentSize + tag4Size + (6 + n * 4) + (6 + n * 2) + tag7Size + (6 + n * 4) + (6 + n * 2) + (6 + n * 2) + (6 + n * 2) + 8;
|
|
894
884
|
const buffer = new ArrayBuffer(bufferSize);
|
|
895
885
|
const view = new DataView(buffer);
|
|
896
886
|
let pos = 0;
|
|
@@ -916,33 +906,45 @@ function buildBinary(data) {
|
|
|
916
906
|
writeUint32(0);
|
|
917
907
|
writeUint16(0);
|
|
918
908
|
writeUint16(1);
|
|
919
|
-
writeUint16(
|
|
920
|
-
|
|
921
|
-
for (let i = 0; i < 8; i++) {
|
|
909
|
+
writeUint16(namePaddedLen);
|
|
910
|
+
for (let i = 0; i < namePaddedLen; i++) {
|
|
922
911
|
writeUint8(nameBytes[i] ?? 0);
|
|
923
912
|
}
|
|
924
913
|
for (const obj of objects) {
|
|
925
914
|
writeUint16(2);
|
|
926
915
|
writeUint16(obj.typeId);
|
|
916
|
+
if (obj.typeId === 100 && obj.text) {
|
|
917
|
+
const textBytes = new TextEncoder().encode(obj.text);
|
|
918
|
+
const paddedLen = Math.max(8, textBytes.length + 1 + 3 & -4);
|
|
919
|
+
writeUint16(3);
|
|
920
|
+
writeUint16(paddedLen);
|
|
921
|
+
for (let i = 0; i < paddedLen; i++) {
|
|
922
|
+
writeUint8(textBytes[i] ?? 0);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
927
925
|
}
|
|
928
926
|
if (n === 0) ; else if (n === 1) {
|
|
929
927
|
writeUint16(4);
|
|
930
928
|
writeUint16(1);
|
|
931
929
|
const obj = objects[0];
|
|
932
930
|
let flagsVal = 1;
|
|
933
|
-
if (obj.hidden)
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
}
|
|
931
|
+
if (obj.hidden) flagsVal &= -2;
|
|
932
|
+
if (obj.horizontalFlip) flagsVal |= 2;
|
|
933
|
+
if (obj.verticalFlip) flagsVal |= 4;
|
|
934
|
+
if (obj.locked) flagsVal |= 8;
|
|
938
935
|
writeUint16(1);
|
|
939
936
|
writeUint16(flagsVal);
|
|
940
937
|
} else {
|
|
941
938
|
writeUint16(4);
|
|
942
939
|
writeUint16(1);
|
|
943
940
|
writeUint16(n);
|
|
944
|
-
for (
|
|
945
|
-
|
|
941
|
+
for (const obj of objects) {
|
|
942
|
+
let flagsVal = 1;
|
|
943
|
+
if (obj.hidden) flagsVal &= -2;
|
|
944
|
+
if (obj.horizontalFlip) flagsVal |= 2;
|
|
945
|
+
if (obj.verticalFlip) flagsVal |= 4;
|
|
946
|
+
if (obj.locked) flagsVal |= 8;
|
|
947
|
+
writeUint16(flagsVal);
|
|
946
948
|
}
|
|
947
949
|
}
|
|
948
950
|
if (n > 0) {
|
|
@@ -957,7 +959,7 @@ function buildBinary(data) {
|
|
|
957
959
|
writeUint16(1);
|
|
958
960
|
writeUint16(n);
|
|
959
961
|
for (const obj of objects) {
|
|
960
|
-
|
|
962
|
+
writeInt16(obj.angle);
|
|
961
963
|
}
|
|
962
964
|
writeUint16(7);
|
|
963
965
|
writeUint16(0);
|
|
@@ -981,19 +983,41 @@ function buildBinary(data) {
|
|
|
981
983
|
writeUint16(1);
|
|
982
984
|
writeUint16(n);
|
|
983
985
|
for (const obj of objects) {
|
|
984
|
-
|
|
986
|
+
if (obj.typeId === 11) {
|
|
987
|
+
writeUint16(obj.width);
|
|
988
|
+
} else if (obj.typeId === 12) {
|
|
989
|
+
writeUint16(Math.round(obj.endX * 10));
|
|
990
|
+
} else if (obj.typeId === 110) {
|
|
991
|
+
writeUint16(obj.horizontalCount);
|
|
992
|
+
} else {
|
|
993
|
+
writeUint16(obj.arcAngle);
|
|
994
|
+
}
|
|
985
995
|
}
|
|
986
996
|
writeUint16(11);
|
|
987
997
|
writeUint16(1);
|
|
988
998
|
writeUint16(n);
|
|
989
999
|
for (const obj of objects) {
|
|
990
|
-
|
|
1000
|
+
if (obj.typeId === 11) {
|
|
1001
|
+
writeUint16(obj.height);
|
|
1002
|
+
} else if (obj.typeId === 12) {
|
|
1003
|
+
writeUint16(Math.round(obj.endY * 10));
|
|
1004
|
+
} else if (obj.typeId === 15) {
|
|
1005
|
+
writeUint16(obj.displayCount);
|
|
1006
|
+
} else if (obj.typeId === 110) {
|
|
1007
|
+
writeUint16(obj.verticalCount);
|
|
1008
|
+
} else {
|
|
1009
|
+
writeUint16(obj.donutRadius);
|
|
1010
|
+
}
|
|
991
1011
|
}
|
|
992
1012
|
writeUint16(12);
|
|
993
1013
|
writeUint16(1);
|
|
994
1014
|
writeUint16(n);
|
|
995
|
-
for (
|
|
996
|
-
|
|
1015
|
+
for (const obj of objects) {
|
|
1016
|
+
if (obj.typeId === 12) {
|
|
1017
|
+
writeUint16(obj.height);
|
|
1018
|
+
} else {
|
|
1019
|
+
writeUint16(0);
|
|
1020
|
+
}
|
|
997
1021
|
}
|
|
998
1022
|
}
|
|
999
1023
|
writeUint16(3);
|