xiv-strat-board 0.1.3 → 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 +87 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +87 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -365,15 +365,6 @@ var BOARD_BACKGROUND_IDS = {
|
|
|
365
365
|
grey_circle: 6,
|
|
366
366
|
grey_square: 7
|
|
367
367
|
};
|
|
368
|
-
var OBJECT_BACKGROUND_IDS = {
|
|
369
|
-
none: 0,
|
|
370
|
-
checkered: 1,
|
|
371
|
-
checkered_circle: 2,
|
|
372
|
-
checkered_square: 3,
|
|
373
|
-
grey: 4,
|
|
374
|
-
grey_circle: 5,
|
|
375
|
-
grey_square: 6
|
|
376
|
-
};
|
|
377
368
|
|
|
378
369
|
// src/validation.ts
|
|
379
370
|
var BOUNDS = {
|
|
@@ -386,9 +377,9 @@ var BOUNDS = {
|
|
|
386
377
|
/** Maximum Y coordinate */
|
|
387
378
|
maxY: 484,
|
|
388
379
|
/** Minimum size percentage */
|
|
389
|
-
minSize:
|
|
380
|
+
minSize: 10,
|
|
390
381
|
/** Maximum size percentage */
|
|
391
|
-
maxSize:
|
|
382
|
+
maxSize: 200,
|
|
392
383
|
/** Minimum arc angle */
|
|
393
384
|
minArc: 0,
|
|
394
385
|
/** Maximum arc angle */
|
|
@@ -399,8 +390,10 @@ var BOUNDS = {
|
|
|
399
390
|
maxDonut: 255,
|
|
400
391
|
/** Maximum number of objects per board */
|
|
401
392
|
maxObjects: 50,
|
|
393
|
+
/** Maximum number of text objects per board */
|
|
394
|
+
maxTextObjects: 8,
|
|
402
395
|
/** Maximum name length (bytes) */
|
|
403
|
-
maxNameLength:
|
|
396
|
+
maxNameLength: 20
|
|
404
397
|
};
|
|
405
398
|
var VALID_CIPHER_CHARS = new Set(
|
|
406
399
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-_".split("")
|
|
@@ -475,19 +468,6 @@ function parseHexColor(color) {
|
|
|
475
468
|
b: parseInt(hex.slice(4, 6), 16)
|
|
476
469
|
};
|
|
477
470
|
}
|
|
478
|
-
function validateBackground(value) {
|
|
479
|
-
if (typeof value === "number") {
|
|
480
|
-
if (value >= 0 && value <= 6) {
|
|
481
|
-
return value;
|
|
482
|
-
}
|
|
483
|
-
return 0;
|
|
484
|
-
}
|
|
485
|
-
if (typeof value === "string") {
|
|
486
|
-
const id = OBJECT_BACKGROUND_IDS[value.toLowerCase()];
|
|
487
|
-
return id ?? 0;
|
|
488
|
-
}
|
|
489
|
-
return 0;
|
|
490
|
-
}
|
|
491
471
|
function validateBoardBackground(value) {
|
|
492
472
|
if (typeof value === "string") {
|
|
493
473
|
const id = BOARD_BACKGROUND_IDS[value.toLowerCase()];
|
|
@@ -538,16 +518,26 @@ function sanitizeObject(obj, index) {
|
|
|
538
518
|
typeId,
|
|
539
519
|
x: sanitizeCoordinate(obj.x, true),
|
|
540
520
|
y: sanitizeCoordinate(obj.y, false),
|
|
541
|
-
size: sanitizeSize(obj.size),
|
|
542
|
-
|
|
521
|
+
size: typeId === 100 ? 100 : sanitizeSize(obj.size),
|
|
522
|
+
angle: Math.round(obj.angle ?? 0),
|
|
543
523
|
colorR: sanitizeColorComponent(colorR),
|
|
544
524
|
colorG: sanitizeColorComponent(colorG),
|
|
545
525
|
colorB: sanitizeColorComponent(colorB),
|
|
546
526
|
transparency: sanitizeColorComponent(obj.transparency ?? 0),
|
|
547
|
-
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),
|
|
548
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) : "",
|
|
549
537
|
hidden: Boolean(obj.hidden),
|
|
550
|
-
locked: Boolean(obj.locked)
|
|
538
|
+
locked: Boolean(obj.locked),
|
|
539
|
+
horizontalFlip: Boolean(obj.horizontalFlip),
|
|
540
|
+
verticalFlip: Boolean(obj.verticalFlip)
|
|
551
541
|
};
|
|
552
542
|
}
|
|
553
543
|
function sanitizeBoard(board) {
|
|
@@ -560,6 +550,10 @@ function sanitizeBoard(board) {
|
|
|
560
550
|
if (board.objects.length > BOUNDS.maxObjects) {
|
|
561
551
|
throw new Error(`Board has too many objects (max ${BOUNDS.maxObjects})`);
|
|
562
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
|
+
}
|
|
563
557
|
return {
|
|
564
558
|
name: sanitizeName(board.name),
|
|
565
559
|
boardBackground: validateBoardBackground(board.boardBackground),
|
|
@@ -783,7 +777,7 @@ function parseBinary(data) {
|
|
|
783
777
|
x: positions[i]?.x ?? 0,
|
|
784
778
|
y: positions[i]?.y ?? 0
|
|
785
779
|
};
|
|
786
|
-
obj.size = sizes[i] && sizes[i] > 0 ? sizes[i] : 100;
|
|
780
|
+
obj.size = iconId === 100 ? 100 : sizes[i] && sizes[i] > 0 ? sizes[i] : 100;
|
|
787
781
|
if (iconId !== 100 && backgrounds[i] !== void 0 && backgrounds[i] !== 0) {
|
|
788
782
|
obj.angle = backgrounds[i];
|
|
789
783
|
}
|
|
@@ -831,10 +825,10 @@ function parseBinary(data) {
|
|
|
831
825
|
obj.verticalCount = tag11[i];
|
|
832
826
|
}
|
|
833
827
|
} else if (iconId === 17) {
|
|
834
|
-
if (tag10[i] && tag10[i] > 0) {
|
|
828
|
+
if (tag10[i] !== void 0 && tag10[i] > 0) {
|
|
835
829
|
obj.arcAngle = tag10[i];
|
|
836
830
|
}
|
|
837
|
-
if (tag11[i]
|
|
831
|
+
if (tag11[i] !== void 0) {
|
|
838
832
|
obj.donutRadius = tag11[i];
|
|
839
833
|
}
|
|
840
834
|
} else {
|
|
@@ -873,9 +867,20 @@ function parseBinary(data) {
|
|
|
873
867
|
function buildBinary(data) {
|
|
874
868
|
const { name, boardBackground, objects } = data;
|
|
875
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;
|
|
876
873
|
const tag4Size = n <= 1 ? 8 : 6 + n * 2;
|
|
877
874
|
const tag7Size = 6 + n + (n % 2 === 1 ? 1 : 0);
|
|
878
|
-
|
|
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;
|
|
879
884
|
const buffer = new ArrayBuffer(bufferSize);
|
|
880
885
|
const view = new DataView(buffer);
|
|
881
886
|
let pos = 0;
|
|
@@ -901,33 +906,45 @@ function buildBinary(data) {
|
|
|
901
906
|
writeUint32(0);
|
|
902
907
|
writeUint16(0);
|
|
903
908
|
writeUint16(1);
|
|
904
|
-
writeUint16(
|
|
905
|
-
|
|
906
|
-
for (let i = 0; i < 8; i++) {
|
|
909
|
+
writeUint16(namePaddedLen);
|
|
910
|
+
for (let i = 0; i < namePaddedLen; i++) {
|
|
907
911
|
writeUint8(nameBytes[i] ?? 0);
|
|
908
912
|
}
|
|
909
913
|
for (const obj of objects) {
|
|
910
914
|
writeUint16(2);
|
|
911
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
|
+
}
|
|
912
925
|
}
|
|
913
926
|
if (n === 0) ; else if (n === 1) {
|
|
914
927
|
writeUint16(4);
|
|
915
928
|
writeUint16(1);
|
|
916
929
|
const obj = objects[0];
|
|
917
930
|
let flagsVal = 1;
|
|
918
|
-
if (obj.hidden)
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
931
|
+
if (obj.hidden) flagsVal &= -2;
|
|
932
|
+
if (obj.horizontalFlip) flagsVal |= 2;
|
|
933
|
+
if (obj.verticalFlip) flagsVal |= 4;
|
|
934
|
+
if (obj.locked) flagsVal |= 8;
|
|
923
935
|
writeUint16(1);
|
|
924
936
|
writeUint16(flagsVal);
|
|
925
937
|
} else {
|
|
926
938
|
writeUint16(4);
|
|
927
939
|
writeUint16(1);
|
|
928
940
|
writeUint16(n);
|
|
929
|
-
for (
|
|
930
|
-
|
|
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);
|
|
931
948
|
}
|
|
932
949
|
}
|
|
933
950
|
if (n > 0) {
|
|
@@ -942,7 +959,7 @@ function buildBinary(data) {
|
|
|
942
959
|
writeUint16(1);
|
|
943
960
|
writeUint16(n);
|
|
944
961
|
for (const obj of objects) {
|
|
945
|
-
|
|
962
|
+
writeInt16(obj.angle);
|
|
946
963
|
}
|
|
947
964
|
writeUint16(7);
|
|
948
965
|
writeUint16(0);
|
|
@@ -966,19 +983,41 @@ function buildBinary(data) {
|
|
|
966
983
|
writeUint16(1);
|
|
967
984
|
writeUint16(n);
|
|
968
985
|
for (const obj of objects) {
|
|
969
|
-
|
|
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
|
+
}
|
|
970
995
|
}
|
|
971
996
|
writeUint16(11);
|
|
972
997
|
writeUint16(1);
|
|
973
998
|
writeUint16(n);
|
|
974
999
|
for (const obj of objects) {
|
|
975
|
-
|
|
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
|
+
}
|
|
976
1011
|
}
|
|
977
1012
|
writeUint16(12);
|
|
978
1013
|
writeUint16(1);
|
|
979
1014
|
writeUint16(n);
|
|
980
|
-
for (
|
|
981
|
-
|
|
1015
|
+
for (const obj of objects) {
|
|
1016
|
+
if (obj.typeId === 12) {
|
|
1017
|
+
writeUint16(obj.height);
|
|
1018
|
+
} else {
|
|
1019
|
+
writeUint16(0);
|
|
1020
|
+
}
|
|
982
1021
|
}
|
|
983
1022
|
}
|
|
984
1023
|
writeUint16(3);
|