@open-feishu-card/adapter 0.3.5 → 0.3.6

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
@@ -604,6 +604,65 @@ function parseMarkdown(content) {
604
604
  return out;
605
605
  }
606
606
 
607
+ // src/expand-dsl-colors.ts
608
+ function readColorRegistry(card) {
609
+ const config = isRecord(card.config) ? card.config : void 0;
610
+ const style = config && isRecord(config.style) ? config.style : void 0;
611
+ const color = style && isRecord(style.color) ? style.color : void 0;
612
+ if (!color) return {};
613
+ const out = {};
614
+ for (const [key, value] of Object.entries(color)) {
615
+ if (!isRecord(value)) continue;
616
+ const light = typeof value.light_mode === "string" ? value.light_mode : typeof value.lightMode === "string" ? value.lightMode : void 0;
617
+ const dark = typeof value.dark_mode === "string" ? value.dark_mode : typeof value.darkMode === "string" ? value.darkMode : void 0;
618
+ if (light && dark) out[key] = { light_mode: light, dark_mode: dark };
619
+ }
620
+ return out;
621
+ }
622
+ function isCustomColorAlias(value) {
623
+ return typeof value === "string" && value.startsWith("cus-");
624
+ }
625
+ function expandBackgroundStyleAlias(style, registry) {
626
+ if (!isCustomColorAlias(style)) return void 0;
627
+ const entry = registry[style];
628
+ if (!entry) return void 0;
629
+ return { light_mode: entry.light_mode, dark_mode: entry.dark_mode };
630
+ }
631
+ function expandTextStyleColor(textStyle, registry) {
632
+ if (!textStyle) return textStyle;
633
+ const color = typeof textStyle.color === "string" ? textStyle.color.trim() : void 0;
634
+ if (!isCustomColorAlias(color)) return textStyle;
635
+ const entry = registry[color];
636
+ if (!entry) return textStyle;
637
+ const { color: _drop, ...rest } = textStyle;
638
+ return {
639
+ ...rest,
640
+ customColor: { lightMode: entry.light_mode, darkMode: entry.dark_mode }
641
+ };
642
+ }
643
+ function expandMarkdownElements(elements, registry) {
644
+ if (!Array.isArray(elements)) return elements;
645
+ return elements.map((el) => {
646
+ const property = el.property ? { ...el.property } : void 0;
647
+ if (!property) return el;
648
+ if (Array.isArray(property.elements)) {
649
+ property.elements = expandMarkdownElements(property.elements, registry);
650
+ }
651
+ if (property.textStyle) {
652
+ const expanded = expandTextStyleColor(property.textStyle, registry);
653
+ if (expanded) property.textStyle = expanded;
654
+ }
655
+ return property === el.property ? el : { ...el, property };
656
+ });
657
+ }
658
+ function wrapMarkdownContentWithFontColor(content, fontColor) {
659
+ if (!fontColor || !content || /<font\s+color/i.test(content)) return content;
660
+ return `<font color='${fontColor}'>${content}</font>`;
661
+ }
662
+ function isRecord(v) {
663
+ return typeof v === "object" && v !== null && !Array.isArray(v);
664
+ }
665
+
607
666
  // src/dsl-to-raw.ts
608
667
  var KEY_RENAME = {
609
668
  text_align: "textAlign",
@@ -629,14 +688,22 @@ var KEY_RENAME = {
629
688
  };
630
689
  var TEXT_LEAF_KEYS = /* @__PURE__ */ new Set(["title", "subtitle", "alt", "hover_tips", "placeholder"]);
631
690
  function dslToRaw(dsl) {
632
- const root = isRecord(dsl) ? dsl : {};
633
- const card = isRecord(root.card) ? root.card : isRecord(root.json_card) ? root.json_card : root;
691
+ const root = isRecord2(dsl) ? dsl : {};
692
+ const card = unwrapCard(root);
693
+ const colors = readColorRegistry(card);
634
694
  const out = { schema: typeof card.schema === "string" ? card.schema : "2.0" };
635
- if (isRecord(card.header)) out.header = convertHeader(card.header);
636
- if (isRecord(card.body)) out.body = convertBody(card.body);
695
+ if (isRecord2(card.config)) out.config = { ...card.config };
696
+ if (isRecord2(card.header)) out.header = convertHeader(card.header, colors);
697
+ if (isRecord2(card.body)) out.body = convertBody(card.body, colors);
637
698
  return out;
638
699
  }
639
- function convertHeader(header) {
700
+ function unwrapCard(root) {
701
+ if (isRecord2(root.dsl)) return root.dsl;
702
+ if (isRecord2(root.card)) return root.card;
703
+ if (isRecord2(root.json_card)) return root.json_card;
704
+ return root;
705
+ }
706
+ function convertHeader(header, colors) {
640
707
  const property = {};
641
708
  for (const [k, v] of Object.entries(header)) {
642
709
  if (k === "tag") continue;
@@ -648,32 +715,32 @@ function convertHeader(header) {
648
715
  property[k] = wrapTextLeaf(v);
649
716
  continue;
650
717
  }
651
- if ((k === "icon" || k === "ud_icon") && isRecord(v)) {
652
- property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v);
718
+ if ((k === "icon" || k === "ud_icon") && isRecord2(v)) {
719
+ property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v, colors);
653
720
  continue;
654
721
  }
655
722
  if (k === "text_tag_list" && Array.isArray(v)) {
656
- property.text_tag_list = v.map(convertNode);
723
+ property.text_tag_list = v.map((item) => convertNode(item, colors));
657
724
  continue;
658
725
  }
659
- property[renameKey(k)] = coerceValue(k, v);
726
+ property[renameKey(k)] = coerceValue(k, v, colors);
660
727
  }
661
728
  return { tag: "card_header", property };
662
729
  }
663
- function convertBody(body) {
664
- const property = buildProperty(body, "body");
665
- const elements = Array.isArray(body.elements) ? body.elements.map(convertNode) : [];
730
+ function convertBody(body, colors) {
731
+ const property = buildProperty(body, "body", colors);
732
+ const elements = Array.isArray(body.elements) ? body.elements.map((n) => convertNode(n, colors)) : [];
666
733
  property.elements = elements.filter(Boolean);
667
734
  return { tag: "body", property };
668
735
  }
669
- function convertNode(node) {
670
- if (isRecord(node) && typeof node.tag === "string") return convertEl(node);
736
+ function convertNode(node, colors) {
737
+ if (isRecord2(node) && typeof node.tag === "string") return convertEl(node, colors);
671
738
  return node;
672
739
  }
673
- function convertEl(el) {
740
+ function convertEl(el, colors) {
674
741
  const tag = String(el.tag);
675
742
  if (tag === "person") {
676
- const property = buildProperty(el, "person_v1");
743
+ const property = buildProperty(el, "person_v1", colors);
677
744
  if (property.style === "capsule") {
678
745
  property.pillShaped = true;
679
746
  delete property.style;
@@ -681,16 +748,22 @@ function convertEl(el) {
681
748
  return { tag: "person_v1", property };
682
749
  }
683
750
  if (tag === "markdown" || tag === "lark_md") {
684
- const property = buildProperty(el, "markdown");
685
- if (typeof el.content === "string") property.elements = parseMarkdown(el.content);
751
+ const property = buildProperty(el, "markdown", colors);
752
+ const fontColor = typeof el.font_color === "string" ? el.font_color : void 0;
753
+ let content = typeof el.content === "string" ? el.content : "";
754
+ content = wrapMarkdownContentWithFontColor(content, fontColor);
755
+ if (content) {
756
+ property.elements = expandMarkdownElements(parseMarkdown(content), colors);
757
+ }
686
758
  delete property.content;
759
+ delete property.font_color;
687
760
  return { tag: "markdown", property };
688
761
  }
689
762
  if (tag === "table") {
690
- return { tag, property: convertTableProperty(el) };
763
+ return { tag, property: convertTableProperty(el, colors) };
691
764
  }
692
765
  if (tag === "audio" || tag === "video") {
693
- const property = buildProperty(el, tag);
766
+ const property = buildProperty(el, tag, colors);
694
767
  if (tag === "audio" && el.width != null) {
695
768
  delete property.width;
696
769
  if (el.width === "fill" || el.width === "default") {
@@ -708,14 +781,14 @@ function convertEl(el) {
708
781
  }
709
782
  return { tag, property };
710
783
  }
711
- return { tag, property: buildProperty(el, tag) };
784
+ return { tag, property: buildProperty(el, tag, colors) };
712
785
  }
713
- function convertTableProperty(el) {
714
- const property = buildProperty(el, "table");
786
+ function convertTableProperty(el, colors) {
787
+ const property = buildProperty(el, "table", colors);
715
788
  const columns = Array.isArray(property.columns) ? property.columns : [];
716
789
  const mdColNames = /* @__PURE__ */ new Set();
717
790
  for (const col of columns) {
718
- if (!isRecord(col)) continue;
791
+ if (!isRecord2(col)) continue;
719
792
  const dt = col.data_type ?? col.dataType;
720
793
  if (dt === "lark_md" || dt === "markdown") {
721
794
  const name = typeof col.name === "string" ? col.name : "";
@@ -724,7 +797,7 @@ function convertTableProperty(el) {
724
797
  }
725
798
  if (!mdColNames.size || !Array.isArray(property.rows)) return property;
726
799
  property.rows = property.rows.map((row) => {
727
- if (!isRecord(row)) return row;
800
+ if (!isRecord2(row)) return row;
728
801
  const out = { ...row };
729
802
  for (const name of mdColNames) {
730
803
  const cell = out[name];
@@ -732,7 +805,10 @@ function convertTableProperty(el) {
732
805
  out[name] = {
733
806
  data: {
734
807
  tag: "markdown",
735
- property: { elements: parseMarkdown(cell), originTag: "lark_md" }
808
+ property: {
809
+ elements: expandMarkdownElements(parseMarkdown(cell), colors),
810
+ originTag: "lark_md"
811
+ }
736
812
  }
737
813
  };
738
814
  }
@@ -741,10 +817,17 @@ function convertTableProperty(el) {
741
817
  });
742
818
  return property;
743
819
  }
744
- function buildProperty(el, tag) {
820
+ function buildProperty(el, tag, colors) {
745
821
  const property = {};
746
822
  for (const [k, v] of Object.entries(el)) {
747
823
  if (k === "tag" || k === "id") continue;
824
+ if ((k === "background_style" || k === "backgroundStyle") && (tag === "column" || tag === "column_set")) {
825
+ const renamed = renameKey(k);
826
+ property[renamed] = v;
827
+ const expanded = expandBackgroundStyleAlias(v, colors);
828
+ if (expanded) property.customBackgroundStyle = expanded;
829
+ continue;
830
+ }
748
831
  if (tag === "column" && k === "width" && typeof v === "string") {
749
832
  const px = pxValue(v);
750
833
  if (px != null) {
@@ -757,15 +840,15 @@ function buildProperty(el, tag) {
757
840
  continue;
758
841
  }
759
842
  if (k === "text") {
760
- if (tag === "checker" && isRecord(v) && (v.tag === "markdown" || v.tag === "lark_md")) {
761
- property.text = convertEl(v);
843
+ if (tag === "checker" && isRecord2(v) && (v.tag === "markdown" || v.tag === "lark_md")) {
844
+ property.text = convertEl(v, colors);
762
845
  } else {
763
846
  property.text = wrapTextLeaf(v);
764
847
  }
765
848
  continue;
766
849
  }
767
- if ((k === "icon" || k === "ud_icon") && isRecord(v)) {
768
- property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v);
850
+ if ((k === "icon" || k === "ud_icon") && isRecord2(v)) {
851
+ property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v, colors);
769
852
  continue;
770
853
  }
771
854
  if (k === "behaviors" && Array.isArray(v)) {
@@ -776,21 +859,21 @@ function buildProperty(el, tag) {
776
859
  property.url = normalizeUrl(v);
777
860
  continue;
778
861
  }
779
- if (k === "button_area" && isRecord(v)) {
862
+ if (k === "button_area" && isRecord2(v)) {
780
863
  const area = { ...v };
781
- if (Array.isArray(v.buttons)) area.buttons = v.buttons.map(convertNode);
864
+ if (Array.isArray(v.buttons)) area.buttons = v.buttons.map((b) => convertNode(b, colors));
782
865
  property.button_area = area;
783
866
  continue;
784
867
  }
785
- property[renameKey(k)] = coerceValue(k, v);
868
+ property[renameKey(k)] = coerceValue(k, v, colors);
786
869
  }
787
870
  return property;
788
871
  }
789
- function coerceValue(key, value) {
872
+ function coerceValue(key, value, colors) {
790
873
  if ((key === "padding" || key === "margin") && typeof value === "string") {
791
874
  return parseBox(value);
792
875
  }
793
- if (Array.isArray(value)) return value.map(convertNode);
876
+ if (Array.isArray(value)) return value.map((item) => convertNode(item, colors));
794
877
  if (key === "url") return normalizeUrl(value);
795
878
  return value;
796
879
  }
@@ -799,7 +882,7 @@ function renameKey(k) {
799
882
  }
800
883
  function wrapTextLeaf(v) {
801
884
  if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
802
- if (isRecord(v)) {
885
+ if (isRecord2(v)) {
803
886
  const property = { content: typeof v.content === "string" ? v.content : "" };
804
887
  if (typeof v.text_align === "string") property.textAlign = v.text_align;
805
888
  if (typeof v.text_size === "string") property.text_size = v.text_size;
@@ -810,7 +893,7 @@ function wrapTextLeaf(v) {
810
893
  }
811
894
  function wrapHeaderText(v) {
812
895
  if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
813
- if (!isRecord(v)) return { tag: "plain_text", property: { content: "" } };
896
+ if (!isRecord2(v)) return { tag: "plain_text", property: { content: "" } };
814
897
  const tag = typeof v.tag === "string" ? v.tag : "plain_text";
815
898
  const content = typeof v.content === "string" ? v.content : "";
816
899
  if (tag === "lark_md" || tag === "markdown") {
@@ -827,7 +910,7 @@ function wrapHeaderText(v) {
827
910
  function behaviorsToActions(behaviors) {
828
911
  const out = [];
829
912
  for (const b of behaviors) {
830
- if (!isRecord(b)) continue;
913
+ if (!isRecord2(b)) continue;
831
914
  const type = typeof b.type === "string" ? b.type : "open_url";
832
915
  out.push({ type, action: { url: normalizeUrl(b.default_url) } });
833
916
  }
@@ -835,7 +918,7 @@ function behaviorsToActions(behaviors) {
835
918
  }
836
919
  function normalizeUrl(v) {
837
920
  if (typeof v === "string") return v;
838
- if (isRecord(v)) return v;
921
+ if (isRecord2(v)) return v;
839
922
  return v;
840
923
  }
841
924
  function parseBox(s) {
@@ -862,7 +945,7 @@ function pxValue(s) {
862
945
  const n = Number(s);
863
946
  return Number.isFinite(n) ? n : null;
864
947
  }
865
- function isRecord(v) {
948
+ function isRecord2(v) {
866
949
  return typeof v === "object" && v !== null && !Array.isArray(v);
867
950
  }
868
951
 
@@ -1227,12 +1310,12 @@ var VALUE_ECHO_TARGETS = {
1227
1310
  size_value: "size"
1228
1311
  };
1229
1312
  function convertRoot(root, ctx) {
1230
- if (!isRecord2(root)) return root;
1313
+ if (!isRecord3(root)) return root;
1231
1314
  const out = {};
1232
1315
  out.schema = typeof root.schema === "string" ? root.schema : "2.0";
1233
- out.config = convertConfig(isRecord2(root.config) ? root.config : {});
1234
- if (isRecord2(root.body)) out.body = convertBody2(root.body, ctx);
1235
- if (isRecord2(root.header)) out.header = convertHeader2(root.header, ctx);
1316
+ out.config = convertConfig(isRecord3(root.config) ? root.config : {});
1317
+ if (isRecord3(root.body)) out.body = convertBody2(root.body, ctx);
1318
+ if (isRecord3(root.header)) out.header = convertHeader2(root.header, ctx);
1236
1319
  normalizeStoredCardColors(out, ctx.colors);
1237
1320
  return out;
1238
1321
  }
@@ -1240,14 +1323,14 @@ function convertConfig(_node) {
1240
1323
  return { update_multi: true };
1241
1324
  }
1242
1325
  function convertHeader2(node, ctx) {
1243
- const property = isRecord2(node.property) ? node.property : node;
1326
+ const property = isRecord3(node.property) ? node.property : node;
1244
1327
  const out = convertProperty(property, "header", ctx);
1245
1328
  delete out.tag;
1246
1329
  return out;
1247
1330
  }
1248
1331
  function convertHeaderText(rawValue, ctx) {
1249
1332
  const tag = typeof rawValue.tag === "string" ? rawValue.tag : "";
1250
- const wrapped = isRecord2(rawValue.property);
1333
+ const wrapped = isRecord3(rawValue.property);
1251
1334
  const property = wrapped ? rawValue.property : rawValue;
1252
1335
  if (tag === "plain_text") {
1253
1336
  const content = typeof property.content === "string" ? property.content : "";
@@ -1267,12 +1350,12 @@ function convertHeaderText(rawValue, ctx) {
1267
1350
  return void 0;
1268
1351
  }
1269
1352
  function convertBody2(node, ctx) {
1270
- const property = isRecord2(node.property) ? node.property : node;
1353
+ const property = isRecord3(node.property) ? node.property : node;
1271
1354
  return convertProperty(property, "body", ctx);
1272
1355
  }
1273
1356
  function unwrap(node, ctx) {
1274
1357
  const tag = typeof node.tag === "string" ? node.tag : void 0;
1275
- const property = isRecord2(node.property) ? node.property : {};
1358
+ const property = isRecord3(node.property) ? node.property : {};
1276
1359
  if (tag === "markdown") return rebuildMarkdown(property, ctx);
1277
1360
  if (tag === "plain_text") {
1278
1361
  const content = typeof property.content === "string" ? property.content : "";
@@ -1286,7 +1369,7 @@ function unwrap(node, ctx) {
1286
1369
  const heightPx = isPixelScalar(property.heightValue) ? pixelOf(property.heightValue) : void 0;
1287
1370
  if (widthPx !== void 0 && heightPx !== void 0) {
1288
1371
  out.size = `${widthPx}px ${heightPx}px`;
1289
- } else if (isRecord2(property.size) && hasSide(property.size)) out.size = formatBox(property.size);
1372
+ } else if (isRecord3(property.size) && hasSide(property.size)) out.size = formatBox(property.size);
1290
1373
  else if (isPixelScalar(property.size)) out.size = `${pixelOf(property.size)}px`;
1291
1374
  else if (typeof property.size === "string") out.size = property.size;
1292
1375
  return out;
@@ -1308,7 +1391,7 @@ function unwrap(node, ctx) {
1308
1391
  const out = { tag: "table" };
1309
1392
  const rawColumns = Array.isArray(property.columns) ? property.columns : [];
1310
1393
  out.columns = rawColumns.map((col) => {
1311
- if (!isRecord2(col)) return {};
1394
+ if (!isRecord3(col)) return {};
1312
1395
  const c = {};
1313
1396
  if (typeof col.name === "string") c.name = col.name;
1314
1397
  const displayName = typeof col.displayName === "string" ? col.displayName : typeof col.display_name === "string" ? col.display_name : void 0;
@@ -1318,22 +1401,22 @@ function unwrap(node, ctx) {
1318
1401
  const hAlign = typeof col.horizontalAlign === "string" ? col.horizontalAlign : typeof col.horizontal_align === "string" ? col.horizontal_align : void 0;
1319
1402
  if (hAlign !== void 0) c.horizontal_align = hAlign;
1320
1403
  const wv = col.widthValue;
1321
- if (isRecord2(wv)) {
1404
+ if (isRecord3(wv)) {
1322
1405
  if (wv.type === "pixels" && typeof wv.value === "number") c.width = `${wv.value}px`;
1323
1406
  else if (typeof wv.value === "string") c.width = wv.value;
1324
1407
  } else if (typeof col.width === "string" || typeof col.width === "number") {
1325
1408
  c.width = col.width;
1326
1409
  }
1327
- if (isRecord2(col.format)) c.format = col.format;
1410
+ if (isRecord3(col.format)) c.format = col.format;
1328
1411
  return c;
1329
1412
  });
1330
1413
  const rawRows = Array.isArray(property.rows) ? property.rows : [];
1331
1414
  out.rows = rawRows.map((row) => {
1332
- if (!isRecord2(row)) return {};
1415
+ if (!isRecord3(row)) return {};
1333
1416
  const r = {};
1334
1417
  for (const [k, cell] of Object.entries(row)) {
1335
- let value = isRecord2(cell) && "data" in cell ? cell.data : cell;
1336
- if (isRecord2(value) && value.tag === "markdown" && isRecord2(value.property)) {
1418
+ let value = isRecord3(cell) && "data" in cell ? cell.data : cell;
1419
+ if (isRecord3(value) && value.tag === "markdown" && isRecord3(value.property)) {
1337
1420
  const elements = Array.isArray(value.property.elements) ? value.property.elements : [];
1338
1421
  value = renderChildren(elements, ctx).content;
1339
1422
  }
@@ -1341,13 +1424,13 @@ function unwrap(node, ctx) {
1341
1424
  }
1342
1425
  return r;
1343
1426
  });
1344
- if (isRecord2(property.headerStyle)) {
1427
+ if (isRecord3(property.headerStyle)) {
1345
1428
  const hs = {};
1346
1429
  for (const [k, v] of Object.entries(property.headerStyle)) {
1347
1430
  const sk = snake(k);
1348
1431
  if (sk === "platform_text_size") continue;
1349
1432
  if (sk === "lines_value") {
1350
- if (isRecord2(v) && typeof v.value === "number") hs.lines = v.value;
1433
+ if (isRecord3(v) && typeof v.value === "number") hs.lines = v.value;
1351
1434
  continue;
1352
1435
  }
1353
1436
  hs[sk] = v;
@@ -1355,7 +1438,7 @@ function unwrap(node, ctx) {
1355
1438
  out.header_style = hs;
1356
1439
  }
1357
1440
  const rhv = property.rowHeightValue;
1358
- if (isRecord2(rhv) && typeof rhv.value === "string") out.row_height = rhv.value;
1441
+ if (isRecord3(rhv) && typeof rhv.value === "string") out.row_height = rhv.value;
1359
1442
  else if (typeof property.rowHeight === "string") out.row_height = property.rowHeight;
1360
1443
  if (typeof property.pageSize === "number") out.page_size = property.pageSize;
1361
1444
  if (typeof property.freezeFirstColumn === "boolean") out.freeze_first_column = property.freezeFirstColumn;
@@ -1390,7 +1473,7 @@ function unwrap(node, ctx) {
1390
1473
  if (typeof property.showAvatar === "boolean") out.show_avatar = property.showAvatar;
1391
1474
  if (typeof property.showName === "boolean") out.show_name = property.showName;
1392
1475
  if (typeof property.style === "string") out.style = property.style;
1393
- if (isRecord2(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1476
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1394
1477
  else if (typeof property.margin === "string") out.margin = property.margin;
1395
1478
  return out;
1396
1479
  }
@@ -1402,17 +1485,17 @@ function unwrap(node, ctx) {
1402
1485
  if (typeof property.lines === "number") out.lines = property.lines;
1403
1486
  if (typeof property.dropInvalidUserID === "boolean") out.drop_invalid_user_id = property.dropInvalidUserID;
1404
1487
  else if (typeof property.drop_invalid_user_id === "boolean") out.drop_invalid_user_id = property.drop_invalid_user_id;
1405
- if (isRecord2(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1488
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1406
1489
  else if (typeof property.margin === "string") out.margin = property.margin;
1407
1490
  const rawPersons = Array.isArray(property.persons) ? property.persons : [];
1408
1491
  out.persons = rawPersons.map((p) => {
1409
- if (!isRecord2(p)) return void 0;
1492
+ if (!isRecord3(p)) return void 0;
1410
1493
  const id = typeof p.id === "string" ? p.id : typeof p.userID === "string" ? p.userID : void 0;
1411
1494
  return id ? { id } : void 0;
1412
1495
  }).filter((p) => p !== void 0);
1413
- const iconSrc = isRecord2(property.icon) ? property.icon : isRecord2(property.udIcon) ? property.udIcon : void 0;
1496
+ const iconSrc = isRecord3(property.icon) ? property.icon : isRecord3(property.udIcon) ? property.udIcon : void 0;
1414
1497
  if (iconSrc) {
1415
- const ip = isRecord2(iconSrc.property) ? iconSrc.property : iconSrc;
1498
+ const ip = isRecord3(iconSrc.property) ? iconSrc.property : iconSrc;
1416
1499
  const icon = {};
1417
1500
  const iconTag = typeof iconSrc.tag === "string" ? iconSrc.tag : typeof ip.tag === "string" ? ip.tag : "standard_icon";
1418
1501
  icon.tag = iconTag === "ud_icon" ? "standard_icon" : iconTag;
@@ -1424,25 +1507,25 @@ function unwrap(node, ctx) {
1424
1507
  }
1425
1508
  return out;
1426
1509
  }
1427
- if (tag === "div" && isRecord2(property.text) && property.fields === void 0) {
1510
+ if (tag === "div" && isRecord3(property.text) && property.fields === void 0) {
1428
1511
  const text = property.text;
1429
1512
  const textTag = typeof text.tag === "string" ? text.tag : "";
1430
- if ((textTag === "markdown" || textTag === "lark_md") && isRecord2(text.property)) {
1513
+ if ((textTag === "markdown" || textTag === "lark_md") && isRecord3(text.property)) {
1431
1514
  return unwrap(text, ctx);
1432
1515
  }
1433
1516
  if (textTag === "plain_text") {
1434
1517
  const out = { tag: "div" };
1435
1518
  const widthVal = property.widthValue;
1436
- if (isRecord2(widthVal) && typeof widthVal.value === "string" && typeof widthVal.type === "string" && widthVal.type.startsWith("builtin_")) {
1519
+ if (isRecord3(widthVal) && typeof widthVal.value === "string" && typeof widthVal.type === "string" && widthVal.type.startsWith("builtin_")) {
1437
1520
  out.width = widthVal.value;
1438
1521
  } else if (typeof property.width === "string") {
1439
1522
  out.width = property.width;
1440
1523
  }
1441
- const tp = isRecord2(text.property) ? text.property : {};
1524
+ const tp = isRecord3(text.property) ? text.property : {};
1442
1525
  const content = typeof tp.content === "string" ? tp.content : "";
1443
1526
  const textAlign = typeof tp.textAlign === "string" ? tp.textAlign : "left";
1444
1527
  out.text = { tag: "plain_text", content, text_align: textAlign };
1445
- if (isRecord2(property.icon)) {
1528
+ if (isRecord3(property.icon)) {
1446
1529
  out.icon = unwrap(property.icon, ctx);
1447
1530
  }
1448
1531
  return out;
@@ -1469,7 +1552,7 @@ function convertProperty(property, ownerTag, ctx) {
1469
1552
  const echoVal = out[echoKey];
1470
1553
  const enumVal = out[enumKey];
1471
1554
  delete out[echoKey];
1472
- if (!isRecord2(echoVal)) continue;
1555
+ if (!isRecord3(echoVal)) continue;
1473
1556
  const echoType = typeof echoVal.type === "string" ? echoVal.type : "";
1474
1557
  const echoValue = echoVal.value;
1475
1558
  if (echoType.includes("pixels") && typeof echoValue === "number") {
@@ -1478,7 +1561,7 @@ function convertProperty(property, ownerTag, ctx) {
1478
1561
  }
1479
1562
  continue;
1480
1563
  }
1481
- if (echoType === "aspect_ratio" && isRecord2(echoValue)) {
1564
+ if (echoType === "aspect_ratio" && isRecord3(echoValue)) {
1482
1565
  const w = echoValue.width;
1483
1566
  const h = echoValue.height;
1484
1567
  if (typeof w === "number" && typeof h === "number") {
@@ -1486,7 +1569,7 @@ function convertProperty(property, ownerTag, ctx) {
1486
1569
  }
1487
1570
  continue;
1488
1571
  }
1489
- if (echoType === "width_height_pixels" && isRecord2(echoValue)) {
1572
+ if (echoType === "width_height_pixels" && isRecord3(echoValue)) {
1490
1573
  const w = echoValue.width;
1491
1574
  const h = echoValue.height;
1492
1575
  if (typeof w === "number" && typeof h === "number") {
@@ -1526,7 +1609,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1526
1609
  if (key === "actions" && Array.isArray(rawValue) && rawValue.length === 0) {
1527
1610
  return DROP;
1528
1611
  }
1529
- if ((key === "padding" || key === "margin") && isRecord2(rawValue) && hasSide(rawValue)) {
1612
+ if ((key === "padding" || key === "margin") && isRecord3(rawValue) && hasSide(rawValue)) {
1530
1613
  return [key, formatBox(rawValue)];
1531
1614
  }
1532
1615
  if (key in VALUE_ECHO_TARGETS) {
@@ -1556,25 +1639,25 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1556
1639
  return DROP;
1557
1640
  }
1558
1641
  if (ownerTag === "video" && VIDEO_RAW_ONLY_FIELDS.has(key)) return DROP;
1559
- if ((key === "alt" || key === "hover_tips") && isRecord2(rawValue) && rawValue.tag === "plain_text") {
1560
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1642
+ if ((key === "alt" || key === "hover_tips") && isRecord3(rawValue) && rawValue.tag === "plain_text") {
1643
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1561
1644
  return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
1562
1645
  }
1563
- if (key === "text" && isRecord2(rawValue) && rawValue.tag === "plain_text") {
1564
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1646
+ if (key === "text" && isRecord3(rawValue) && rawValue.tag === "plain_text") {
1647
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1565
1648
  return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
1566
1649
  }
1567
- if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord2(rawValue)) {
1650
+ if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord3(rawValue)) {
1568
1651
  const headerText = convertHeaderText(rawValue, ctx);
1569
1652
  if (headerText) return [key, headerText];
1570
1653
  }
1571
- if (ownerTag === "header" && key === "ud_icon" && isRecord2(rawValue) && rawValue.tag === "ud_icon") {
1572
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1654
+ if (ownerTag === "header" && key === "ud_icon" && isRecord3(rawValue) && rawValue.tag === "ud_icon") {
1655
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1573
1656
  const token = typeof p.token === "string" ? p.token : void 0;
1574
1657
  if (!token) return DROP;
1575
1658
  return ["icon", { tag: "standard_icon", token }];
1576
1659
  }
1577
- if (ownerTag === "collapsible_panel" && key === "header" && isRecord2(rawValue)) {
1660
+ if (ownerTag === "collapsible_panel" && key === "header" && isRecord3(rawValue)) {
1578
1661
  const cleaned = {};
1579
1662
  for (const [k, v] of Object.entries(rawValue)) {
1580
1663
  const sk = snake(k);
@@ -1591,8 +1674,8 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1591
1674
  if (ownerTag === "button" && key === "actions" && Array.isArray(rawValue)) {
1592
1675
  const openUrls = [];
1593
1676
  for (const a of rawValue) {
1594
- if (!isRecord2(a)) continue;
1595
- const inner = isRecord2(a.action) ? a.action : {};
1677
+ if (!isRecord3(a)) continue;
1678
+ const inner = isRecord3(a.action) ? a.action : {};
1596
1679
  const t = typeof a.type === "string" ? a.type : void 0;
1597
1680
  if (t === "open_url" && typeof inner.url === "string") openUrls.push(inner.url);
1598
1681
  }
@@ -1607,8 +1690,8 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1607
1690
  }
1608
1691
  if (ownerTag === "interactive_container" && key === "actions" && Array.isArray(rawValue)) {
1609
1692
  const behaviors = rawValue.map((a) => {
1610
- if (!isRecord2(a)) return void 0;
1611
- const inner = isRecord2(a.action) ? a.action : {};
1693
+ if (!isRecord3(a)) return void 0;
1694
+ const inner = isRecord3(a.action) ? a.action : {};
1612
1695
  const t = typeof a.type === "string" ? a.type : void 0;
1613
1696
  if (t === "open_url" && typeof inner.url === "string") {
1614
1697
  return { type: "open_url", default_url: inner.url };
@@ -1621,7 +1704,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1621
1704
  if (behaviors.length === 0) return DROP;
1622
1705
  return ["behaviors", behaviors];
1623
1706
  }
1624
- if (key === "border" && isRecord2(rawValue)) {
1707
+ if (key === "border" && isRecord3(rawValue)) {
1625
1708
  const b = rawValue;
1626
1709
  const out = {};
1627
1710
  if (typeof b.borderColor === "string") out.color = b.borderColor;
@@ -1635,7 +1718,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1635
1718
  }
1636
1719
  return [key, out];
1637
1720
  }
1638
- if (key === "url" && isRecord2(rawValue)) {
1721
+ if (key === "url" && isRecord3(rawValue)) {
1639
1722
  const v = rawValue;
1640
1723
  const main = typeof v.url === "string" ? v.url : "";
1641
1724
  const others = ["androidURL", "iosURL", "pcURL", "harmonyURL"].map((k) => v[k]).filter((x) => typeof x === "string" && x.length > 0);
@@ -1676,7 +1759,7 @@ function renderInlineAudio(prop) {
1676
1759
  if (bg) attrs.push(`background_color='${bg}'`);
1677
1760
  const fill = typeof prop.fillColor === "string" ? prop.fillColor : typeof prop.fill_color === "string" ? prop.fill_color : void 0;
1678
1761
  if (fill) attrs.push(`fill_color='${fill}'`);
1679
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1762
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1680
1763
  if (urlObj) {
1681
1764
  if (typeof urlObj.url === "string" && urlObj.url) attrs.push(`fallback_url='${urlObj.url}'`);
1682
1765
  if (typeof urlObj.pcURL === "string" && urlObj.pcURL) attrs.push(`fallback_pc_url='${urlObj.pcURL}'`);
@@ -1690,9 +1773,9 @@ function renderInlineAudio(prop) {
1690
1773
  } else if (typeof prop.fallback_url === "string" && prop.fallback_url) {
1691
1774
  attrs.push(`fallback_url='${prop.fallback_url}'`);
1692
1775
  }
1693
- const fb = isRecord2(prop.fallbackText) ? prop.fallbackText : isRecord2(prop.fallback_text) ? prop.fallback_text : void 0;
1776
+ const fb = isRecord3(prop.fallbackText) ? prop.fallbackText : isRecord3(prop.fallback_text) ? prop.fallback_text : void 0;
1694
1777
  if (fb) {
1695
- const fbProp = isRecord2(fb.property) ? fb.property : fb;
1778
+ const fbProp = isRecord3(fb.property) ? fb.property : fb;
1696
1779
  const fbContent = typeof fbProp.content === "string" ? fbProp.content : typeof fb.content === "string" ? fb.content : "";
1697
1780
  if (fbContent) attrs.push(`fallback_text='${fbContent}'`);
1698
1781
  }
@@ -1716,7 +1799,7 @@ function rebuildMarkdown(property, ctx) {
1716
1799
  if (rawKey === "elements" || rawKey === "markdownElements" || rawKey === "originTag") continue;
1717
1800
  if (rawKey === "udIcon") continue;
1718
1801
  if (rawKey === "textStyle") {
1719
- const ts = isRecord2(rawValue) ? rawValue : {};
1802
+ const ts = isRecord3(rawValue) ? rawValue : {};
1720
1803
  const size = typeof ts.size === "string" ? ts.size : void 0;
1721
1804
  if (size) out.text_size = size;
1722
1805
  continue;
@@ -1792,7 +1875,7 @@ function renderChildren(children, ctx) {
1792
1875
  buffer = [];
1793
1876
  }
1794
1877
  for (const child of children) {
1795
- if (!isRecord2(child)) continue;
1878
+ if (!isRecord3(child)) continue;
1796
1879
  const inline = childToInlineSegment(child, ctx);
1797
1880
  if (inline) {
1798
1881
  buffer.push(inline);
@@ -1806,8 +1889,8 @@ function renderChildren(children, ctx) {
1806
1889
  }
1807
1890
  function childToInlineSegment(child, ctx) {
1808
1891
  const tag = child.tag;
1809
- const prop = isRecord2(child.property) ? child.property : {};
1810
- const ts = isRecord2(prop.textStyle) ? prop.textStyle : void 0;
1892
+ const prop = isRecord3(child.property) ? child.property : {};
1893
+ const ts = isRecord3(prop.textStyle) ? prop.textStyle : void 0;
1811
1894
  const { bold, color, colorKind } = resolveInlineStyle(ts, ctx);
1812
1895
  switch (tag) {
1813
1896
  case "plain_text":
@@ -1826,7 +1909,7 @@ function childToInlineSegment(child, ctx) {
1826
1909
  };
1827
1910
  case "link": {
1828
1911
  const text = typeof prop.content === "string" ? prop.content : "";
1829
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1912
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1830
1913
  const url = urlObj && typeof urlObj.url === "string" ? urlObj.url : "";
1831
1914
  return { content: `[${text}](${url})`, bold, color, colorKind };
1832
1915
  }
@@ -1838,8 +1921,8 @@ function childToInlineSegment(child, ctx) {
1838
1921
  }
1839
1922
  case "text_tag": {
1840
1923
  const tagColor = typeof prop.color === "string" ? prop.color : void 0;
1841
- const inner = isRecord2(prop.text) ? prop.text : void 0;
1842
- const innerProp = inner && isRecord2(inner.property) ? inner.property : void 0;
1924
+ const inner = isRecord3(prop.text) ? prop.text : void 0;
1925
+ const innerProp = inner && isRecord3(inner.property) ? inner.property : void 0;
1843
1926
  const innerContent = innerProp && typeof innerProp.content === "string" ? innerProp.content : "";
1844
1927
  const rendered = tagColor ? `<text_tag color='${tagColor}'>${innerContent}</text_tag>` : `<text_tag>${innerContent}</text_tag>`;
1845
1928
  return { content: rendered, bold: false };
@@ -1863,11 +1946,11 @@ function childToInlineSegment(child, ctx) {
1863
1946
  }
1864
1947
  function childToMarkdown(child, ctx) {
1865
1948
  const tag = child.tag;
1866
- const prop = isRecord2(child.property) ? child.property : {};
1949
+ const prop = isRecord3(child.property) ? child.property : {};
1867
1950
  switch (tag) {
1868
1951
  case "plain_text": {
1869
1952
  const content = typeof prop.content === "string" ? prop.content : "";
1870
- const ts = isRecord2(prop.textStyle) ? prop.textStyle : void 0;
1953
+ const ts = isRecord3(prop.textStyle) ? prop.textStyle : void 0;
1871
1954
  const { bold, color } = resolveInlineStyle(ts, ctx);
1872
1955
  return wrapEmphasis(content, bold, color);
1873
1956
  }
@@ -1890,7 +1973,7 @@ function childToMarkdown(child, ctx) {
1890
1973
  return renderInlineAudio(prop);
1891
1974
  case "link": {
1892
1975
  const text = typeof prop.content === "string" ? prop.content : "";
1893
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1976
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1894
1977
  const url = urlObj && typeof urlObj.url === "string" ? urlObj.url : "";
1895
1978
  return `[${text}](${url})`;
1896
1979
  }
@@ -1900,8 +1983,8 @@ function childToMarkdown(child, ctx) {
1900
1983
  }
1901
1984
  case "text_tag": {
1902
1985
  const color = typeof prop.color === "string" ? prop.color : void 0;
1903
- const inner = isRecord2(prop.text) ? prop.text : void 0;
1904
- const innerProp = inner && isRecord2(inner.property) ? inner.property : void 0;
1986
+ const inner = isRecord3(prop.text) ? prop.text : void 0;
1987
+ const innerProp = inner && isRecord3(inner.property) ? inner.property : void 0;
1905
1988
  const innerContent = innerProp && typeof innerProp.content === "string" ? innerProp.content : "";
1906
1989
  if (color) return `<text_tag color='${color}'>${innerContent}</text_tag>`;
1907
1990
  return `<text_tag>${innerContent}</text_tag>`;
@@ -1910,11 +1993,11 @@ function childToMarkdown(child, ctx) {
1910
1993
  const lang = typeof prop.language === "string" ? prop.language : "";
1911
1994
  const blocks = Array.isArray(prop.contents) ? prop.contents : [];
1912
1995
  const lines = blocks.map((blk) => {
1913
- if (!isRecord2(blk)) return "";
1996
+ if (!isRecord3(blk)) return "";
1914
1997
  const inner = Array.isArray(blk.contents) ? blk.contents : [];
1915
1998
  let line = "";
1916
1999
  for (const seg of inner) {
1917
- if (isRecord2(seg) && typeof seg.content === "string") line += seg.content;
2000
+ if (isRecord3(seg) && typeof seg.content === "string") line += seg.content;
1918
2001
  }
1919
2002
  return line;
1920
2003
  });
@@ -1930,14 +2013,14 @@ ${body}
1930
2013
  const lines = [];
1931
2014
  const levelCounters = [];
1932
2015
  for (const item of items) {
1933
- if (!isRecord2(item)) continue;
2016
+ if (!isRecord3(item)) continue;
1934
2017
  const level = typeof item.level === "number" ? item.level : 0;
1935
2018
  const type = typeof item.type === "string" ? item.type : "ul";
1936
2019
  const indent = " ".repeat(level);
1937
2020
  const inner = Array.isArray(item.elements) ? item.elements : [];
1938
2021
  let text = "";
1939
2022
  for (const seg of inner) {
1940
- if (!isRecord2(seg)) continue;
2023
+ if (!isRecord3(seg)) continue;
1941
2024
  text += childToMarkdown(seg, ctx);
1942
2025
  }
1943
2026
  if (type === "ol") {
@@ -1966,7 +2049,7 @@ ${lines.join("\n")}
1966
2049
  const inner = Array.isArray(prop.elements) ? prop.elements : [];
1967
2050
  let body = "";
1968
2051
  for (const seg of inner) {
1969
- if (isRecord2(seg)) body += childToMarkdown(seg, ctx);
2052
+ if (isRecord3(seg)) body += childToMarkdown(seg, ctx);
1970
2053
  }
1971
2054
  return `
1972
2055
 
@@ -1982,18 +2065,18 @@ ${"#".repeat(level)} ${body}
1982
2065
  const rows = Array.isArray(prop.rows) ? prop.rows : [];
1983
2066
  if (columns.length === 0) return "";
1984
2067
  const headers = columns.map(
1985
- (col) => isRecord2(col) && typeof col.displayName === "string" ? col.displayName : ""
2068
+ (col) => isRecord3(col) && typeof col.displayName === "string" ? col.displayName : ""
1986
2069
  );
1987
2070
  const headerLine = `| ${headers.join(" | ")} |`;
1988
2071
  const separator = `| ${columns.map(() => "--------").join(" | ")} |`;
1989
2072
  const bodyLines = rows.map((row) => {
1990
- if (!isRecord2(row)) return `| ${columns.map(() => "").join(" | ")} |`;
2073
+ if (!isRecord3(row)) return `| ${columns.map(() => "").join(" | ")} |`;
1991
2074
  const cells = columns.map((col) => {
1992
- const name = isRecord2(col) && typeof col.name === "string" ? col.name : "";
1993
- const cell = isRecord2(row[name]) ? row[name] : void 0;
1994
- const data = cell && isRecord2(cell.data) ? cell.data : void 0;
2075
+ const name = isRecord3(col) && typeof col.name === "string" ? col.name : "";
2076
+ const cell = isRecord3(row[name]) ? row[name] : void 0;
2077
+ const data = cell && isRecord3(cell.data) ? cell.data : void 0;
1995
2078
  if (!data || data.tag !== "markdown") return "";
1996
- const cellProp = isRecord2(data.property) ? data.property : {};
2079
+ const cellProp = isRecord3(data.property) ? data.property : {};
1997
2080
  const inner = Array.isArray(cellProp.elements) ? cellProp.elements : [];
1998
2081
  const { content: text } = renderChildren(inner, ctx);
1999
2082
  return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
@@ -2012,7 +2095,7 @@ ${bodyLines.join("\n")}
2012
2095
  const inner = Array.isArray(prop.elements) ? prop.elements : [];
2013
2096
  let body = "";
2014
2097
  for (const seg of inner) {
2015
- if (isRecord2(seg)) body += childToMarkdown(seg, ctx);
2098
+ if (isRecord3(seg)) body += childToMarkdown(seg, ctx);
2016
2099
  }
2017
2100
  return `
2018
2101
 
@@ -2027,14 +2110,14 @@ ${bodyLines.join("\n")}
2027
2110
  function convertGeneric(value, ctx) {
2028
2111
  if (Array.isArray(value)) {
2029
2112
  return value.map((item) => {
2030
- if (isRecord2(item) && typeof item.tag === "string" && isRecord2(item.property)) {
2113
+ if (isRecord3(item) && typeof item.tag === "string" && isRecord3(item.property)) {
2031
2114
  return unwrap(item, ctx);
2032
2115
  }
2033
2116
  return convertGeneric(item, ctx);
2034
2117
  });
2035
2118
  }
2036
- if (isRecord2(value)) {
2037
- if (typeof value.tag === "string" && isRecord2(value.property)) {
2119
+ if (isRecord3(value)) {
2120
+ if (typeof value.tag === "string" && isRecord3(value.property)) {
2038
2121
  return unwrap(value, ctx);
2039
2122
  }
2040
2123
  if (hasSide(value)) {
@@ -2051,7 +2134,7 @@ function convertGeneric(value, ctx) {
2051
2134
  }
2052
2135
  return value;
2053
2136
  }
2054
- function isRecord2(v) {
2137
+ function isRecord3(v) {
2055
2138
  return typeof v === "object" && v !== null && !Array.isArray(v);
2056
2139
  }
2057
2140
  function resolveAttachmentImgKey(rawValue, ctx) {
@@ -2067,7 +2150,7 @@ function normalizeVideoCover(rawValue, ctx) {
2067
2150
  const imgKey2 = resolveAttachmentImgKey(rawValue, ctx);
2068
2151
  return imgKey2 ? { img_key: imgKey2 } : void 0;
2069
2152
  }
2070
- if (!isRecord2(rawValue)) return void 0;
2153
+ if (!isRecord3(rawValue)) return void 0;
2071
2154
  if (typeof rawValue.img_key === "string" && rawValue.img_key) {
2072
2155
  return { img_key: rawValue.img_key };
2073
2156
  }
@@ -2076,17 +2159,17 @@ function normalizeVideoCover(rawValue, ctx) {
2076
2159
  return imgKey ? { img_key: imgKey } : void 0;
2077
2160
  }
2078
2161
  function hasSide(v) {
2079
- return ("top" in v || "bottom" in v || "left" in v || "right" in v) && Object.values(v).some((side) => isRecord2(side) && "type" in side && "value" in side);
2162
+ return ("top" in v || "bottom" in v || "left" in v || "right" in v) && Object.values(v).some((side) => isRecord3(side) && "type" in side && "value" in side);
2080
2163
  }
2081
2164
  function formatBox(v) {
2082
2165
  return `${pixelOf(v.top)}px ${pixelOf(v.right)}px ${pixelOf(v.bottom)}px ${pixelOf(v.left)}px`;
2083
2166
  }
2084
2167
  function isPixelScalar(v) {
2085
- if (!isRecord2(v)) return false;
2168
+ if (!isRecord3(v)) return false;
2086
2169
  return typeof v.type === "string" && v.type.includes("pixels") && typeof v.value === "number";
2087
2170
  }
2088
2171
  function pixelOf(side) {
2089
- if (!isRecord2(side)) return 0;
2172
+ if (!isRecord3(side)) return 0;
2090
2173
  const v = side.value;
2091
2174
  if (typeof v === "number") return v;
2092
2175
  if (typeof v === "string") {
@@ -2107,8 +2190,8 @@ function rawToDsl(raw) {
2107
2190
  return raw;
2108
2191
  }
2109
2192
  }
2110
- if (!isRecord2(raw)) return raw;
2111
- if (typeof raw.json_card === "string" || isRecord2(raw.json_card)) {
2193
+ if (!isRecord3(raw)) return raw;
2194
+ if (typeof raw.json_card === "string" || isRecord3(raw.json_card)) {
2112
2195
  let inner = raw.json_card;
2113
2196
  if (typeof inner === "string") {
2114
2197
  try {
@@ -2117,16 +2200,16 @@ function rawToDsl(raw) {
2117
2200
  return raw;
2118
2201
  }
2119
2202
  }
2120
- const attachment = isRecord2(raw.json_attachment) ? raw.json_attachment : {};
2203
+ const attachment = isRecord3(raw.json_attachment) ? raw.json_attachment : {};
2121
2204
  const ctx = makeCtx({
2122
- images: isRecord2(attachment.images) ? attachment.images : {},
2123
- atUsers: isRecord2(attachment.at_users) ? attachment.at_users : {}
2205
+ images: isRecord3(attachment.images) ? attachment.images : {},
2206
+ atUsers: isRecord3(attachment.at_users) ? attachment.at_users : {}
2124
2207
  });
2125
2208
  return convertRoot(inner, ctx);
2126
2209
  }
2127
- if (isRecord2(raw.card)) {
2210
+ if (isRecord3(raw.card)) {
2128
2211
  const card = raw.card;
2129
- if (typeof card.json_card === "string" || isRecord2(card.json_card)) {
2212
+ if (typeof card.json_card === "string" || isRecord3(card.json_card)) {
2130
2213
  return rawToDsl(card);
2131
2214
  }
2132
2215
  return convertRoot(card, makeCtx());