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/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: 1,
380
+ minSize: 10,
390
381
  /** Maximum size percentage */
391
- maxSize: 255,
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: 7
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
- background: validateBackground(obj.background),
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] && tag11[i] > 0) {
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
- const bufferSize = n === 0 ? 36 + 8 : 36 + n * 4 + tag4Size + (6 + n * 4) + (6 + n * 2) + tag7Size + (6 + n * 4) + (6 + n * 2) + (6 + n * 2) + (6 + n * 2) + 8;
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(8);
905
- const nameBytes = new TextEncoder().encode(name.slice(0, 7));
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
- flagsVal = 0;
920
- } else if (obj.locked) {
921
- flagsVal = 9;
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 (let i = 0; i < n; i++) {
930
- writeUint16(1);
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
- writeUint16(obj.background);
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
- writeUint16(obj.arcAngle);
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
- writeUint16(obj.donutRadius);
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 (let i = 0; i < n; i++) {
981
- writeUint16(0);
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);