@examind/block-sdk 0.1.4 → 0.1.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
@@ -93,12 +93,12 @@ var EssayQuestionNodeHandler = class extends NodeHandler {
93
93
 
94
94
  // src/typeGuards/isSerializedFillInTheBlankQuestionNode.ts
95
95
  function isSerializedFillInTheBlankQuestionNode(node) {
96
- return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "content" in node && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number";
96
+ return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number" && "content" in node;
97
97
  }
98
98
 
99
99
  // src/typeGuards/isSerializedParagraphNode.ts
100
100
  function isSerializedParagraphNode(node) {
101
- return node?.type === "paragraph" && "children" in node && Array.isArray(node.children);
101
+ return node?.type === "paragraph" && "textFormat" in node && typeof node.textFormat === "number" && "textStyle" in node && typeof node.textStyle === "string";
102
102
  }
103
103
 
104
104
  // src/exportToHtml/createHtmlFromNestedNodes.ts
@@ -136,7 +136,7 @@ var FillInTheBlankQuestionNodeHandler = class extends NodeHandler {
136
136
 
137
137
  // src/typeGuards/isSerializedFillInTheBlankSpaceNode.ts
138
138
  function isSerializedFillInTheBlankSpaceNode(node) {
139
- return node?.type === "space" && "id" in node && typeof node.id === "string" && "spaceType" in node && "matches" in node && typeof node.matches === "string";
139
+ return node?.type === "space" && "id" in node && typeof node.id === "string" && "spaceName" in node && typeof node.spaceName === "string" && "matches" in node && typeof node.matches === "string" && "spaceType" in node;
140
140
  }
141
141
 
142
142
  // src/exportToHtml/FillInTheBlankSpaceNodeHandler.ts
@@ -177,7 +177,7 @@ var FillInTheBlankSpaceNodeHandler = class extends NodeHandler {
177
177
 
178
178
  // src/typeGuards/isSerializedFinancialStatementQuestionNode.ts
179
179
  function isSerializedFinancialStatementQuestionNode(node) {
180
- return node?.type === "financial-statement-question" && "id" in node && typeof node.id === "string" && "header" in node && "rows" in node && Array.isArray(node.rows) && "points" in node && typeof node.points === "number";
180
+ return node?.type === "financial-statement-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "header" in node && "columnHeaders" in node && Array.isArray(node.columnHeaders) && "rows" in node && Array.isArray(node.rows) && "distractors" in node && Array.isArray(node.distractors);
181
181
  }
182
182
 
183
183
  // src/exportToHtml/FinancialStatementQuestionNodeHandler.ts
@@ -243,7 +243,7 @@ var FinancialStatementQuestionNodeHandler = class extends NodeHandler {
243
243
 
244
244
  // src/typeGuards/isSerializedHorizontalRuleNode.ts
245
245
  var isSerializedHorizontalRuleNode = (node) => {
246
- return node.type === "horizontalrule";
246
+ return node?.type === "horizontalrule";
247
247
  };
248
248
 
249
249
  // src/exportToHtml/HorizontalRuleNodeHandler.ts
@@ -256,7 +256,7 @@ var HorizontalRuleNodeHandler = class extends NodeHandler {
256
256
 
257
257
  // src/typeGuards/isSerializedImageNode.ts
258
258
  var isSerializedImageNode = (node) => {
259
- return node.type === "image";
259
+ return node?.type === "image" && "altText" in node && typeof node.altText === "string" && "caption" in node && "showCaption" in node && typeof node.showCaption === "boolean" && "src" in node && typeof node.src === "string" && "width" in node && typeof node.width === "string" && "align" in node && typeof node.align === "string" && "showBorder" in node && typeof node.showBorder === "boolean";
260
260
  };
261
261
 
262
262
  // src/exportToHtml/ImageNodeHandler.ts
@@ -275,7 +275,7 @@ var ImageNodeHandler = class extends NodeHandler {
275
275
 
276
276
  // src/typeGuards/isSerializedJournalEntryQuestionNode.ts
277
277
  function isSerializedJournalEntryQuestionNode(node) {
278
- return node?.type === "journal-entry-question" && "id" in node && typeof node.id === "string" && "lineItems" in node && Array.isArray(node.lineItems) && "points" in node && typeof node.points === "number";
278
+ return node?.type === "journal-entry-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "journalType" in node && typeof node.journalType === "string" && "lineItems" in node && Array.isArray(node.lineItems);
279
279
  }
280
280
 
281
281
  // src/exportToHtml/JournalEntryQuestionNodeHandler.ts
@@ -357,7 +357,7 @@ var LineBreakNodeHandler = class extends NodeHandler {
357
357
 
358
358
  // src/typeGuards/isSerializedLinkNode.ts
359
359
  var isSerializedLinkNode = (node) => {
360
- return node.type === "link";
360
+ return node?.type === "link" && "url" in node && typeof node.url === "string";
361
361
  };
362
362
 
363
363
  // src/exportToHtml/LinkNodeHandler.ts
@@ -374,7 +374,7 @@ var LinkNodeHandler = class extends NodeHandler {
374
374
 
375
375
  // src/typeGuards/isSerializedListItemNode.ts
376
376
  var isSerializedListItemNode = (node) => {
377
- return node.type === "listitem";
377
+ return node?.type === "listitem" && "value" in node && typeof node.value === "number";
378
378
  };
379
379
 
380
380
  // src/exportToHtml/ListItemNodeHandler.ts
@@ -397,7 +397,7 @@ var ListItemNodeHandler = class extends NodeHandler {
397
397
 
398
398
  // src/typeGuards/isSerializedListNode.ts
399
399
  var isSerializedListNode = (node) => {
400
- return node !== void 0 && node.type === "list";
400
+ return node?.type === "list" && "listType" in node && typeof node.listType === "string" && "start" in node && typeof node.start === "number" && "tag" in node && typeof node.tag === "string";
401
401
  };
402
402
 
403
403
  // src/exportToHtml/ListNodeHandler.ts
@@ -421,7 +421,7 @@ var ListNodeHandler = class extends NodeHandler {
421
421
 
422
422
  // src/typeGuards/isSerializedMatchingQuestionNode.ts
423
423
  function isSerializedMatchingQuestionNode(node) {
424
- return node?.type === "matching-question" && "id" in node && typeof node.id === "string" && "items" in node && Array.isArray(node.items) && "pointsPerMatch" in node && typeof node.pointsPerMatch === "number";
424
+ return node?.type === "matching-question" && "id" in node && typeof node.id === "string" && "pointsPerMatch" in node && typeof node.pointsPerMatch === "number" && "items" in node && Array.isArray(node.items);
425
425
  }
426
426
 
427
427
  // src/exportToHtml/MatchingQuestionNodeHandler.ts
@@ -461,7 +461,7 @@ var MatchingQuestionNodeHandler = class extends NodeHandler {
461
461
 
462
462
  // src/typeGuards/isSerializedMultipleOptionQuestionNode.ts
463
463
  function isSerializedMultipleOptionQuestionNode(node) {
464
- return node?.type === "multiple-option-question" && "id" in node && typeof node.id === "string" && "options" in node && Array.isArray(node.options) && "questionType" in node && typeof node.questionType === "string" && "points" in node && typeof node.points === "number";
464
+ return node?.type === "multiple-option-question" && "id" in node && typeof node.id === "string" && "questionType" in node && typeof node.questionType === "string" && "points" in node && typeof node.points === "number" && "options" in node && Array.isArray(node.options);
465
465
  }
466
466
 
467
467
  // src/exportToHtml/MultipleOptionQuestionNodeHandler.ts
@@ -530,7 +530,7 @@ function isSerializedShortAnswerQuestionNode(node) {
530
530
 
531
531
  // src/typeGuards/isSerializedTableCellNode.ts
532
532
  function isSerializedTableCellNode(node) {
533
- return node?.type === "tablecell";
533
+ return node?.type === "tablecell" && "headerState" in node && typeof node.headerState === "number";
534
534
  }
535
535
 
536
536
  // src/exportToHtml/ParagraphNodeHandler.ts
@@ -594,7 +594,7 @@ var ShortAnswerQuestionNodeHandler = class extends NodeHandler {
594
594
 
595
595
  // src/typeGuards/isSerializedSimulationQuestionNode.ts
596
596
  function isSerializedSimulationQuestionNode(node) {
597
- return node?.type === "simulation-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "step2Instructions" in node && typeof node.step2Instructions === "string";
597
+ return node?.type === "simulation-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number";
598
598
  }
599
599
 
600
600
  // src/exportToHtml/SimulationQuestionNodeHandler.ts
@@ -610,7 +610,7 @@ var SimulationQuestionNodeHandler = class extends NodeHandler {
610
610
 
611
611
  // src/typeGuards/isSerializedTableRowNode.ts
612
612
  function isSerializedTableRowNode(node) {
613
- return node?.type === "tablerow" && "children" in node && Array.isArray(node.children);
613
+ return node?.type === "tablerow";
614
614
  }
615
615
 
616
616
  // src/exportToHtml/TableCellNodeHandler.ts
@@ -629,9 +629,10 @@ var TableCellNodeHandler = class extends NodeHandler {
629
629
  }
630
630
  }
631
631
  }
632
- if (metadata?.colWidthPixels && cellIndex >= 0 && cellIndex < metadata.colWidthPixels.length) {
632
+ const hasColspan = tableCellNode.colSpan && tableCellNode.colSpan > 1;
633
+ if (!hasColspan && metadata?.colWidthPixels && cellIndex >= 0 && cellIndex < metadata.colWidthPixels.length) {
633
634
  styles.push(`width: ${metadata.colWidthPixels[cellIndex]}px;`);
634
- } else if (tableCellNode.width) {
635
+ } else if (!hasColspan && tableCellNode.width) {
635
636
  styles.push(`width: ${tableCellNode.width}px;`);
636
637
  }
637
638
  if (tableCellNode.backgroundColor) {
@@ -644,13 +645,14 @@ var TableCellNodeHandler = class extends NodeHandler {
644
645
  }
645
646
  const styleAttr = styles.length > 0 ? ` style="${styles.join(" ")}"` : "";
646
647
  const tag = tableCellNode.headerState > 0 ? "th" : "td";
647
- return `<${tag}${styleAttr}>${createHtmlFromNestedNodes(tableCellNode.children, { parentNode: tableCellNode })}</${tag}>`;
648
+ const colspanAttr = tableCellNode.colSpan && tableCellNode.colSpan > 1 ? ` colspan="${tableCellNode.colSpan}"` : "";
649
+ return `<${tag}${styleAttr}${colspanAttr}>${createHtmlFromNestedNodes(tableCellNode.children, { parentNode: tableCellNode })}</${tag}>`;
648
650
  }
649
651
  };
650
652
 
651
653
  // src/typeGuards/isSerializedTableNode.ts
652
654
  function isSerializedTableNode(node) {
653
- return node?.type === "table" && "children" in node && Array.isArray(node.children);
655
+ return node?.type === "table";
654
656
  }
655
657
 
656
658
  // src/exportToHtml/TableNodeHandler.ts
@@ -730,7 +732,7 @@ var TableRowNodeHandler = class extends NodeHandler {
730
732
 
731
733
  // src/typeGuards/isSerializedTextNode.ts
732
734
  function isSerializedTextNode(node) {
733
- return node?.type === "text" && "text" in node && typeof node.text === "string";
735
+ return node?.type === "text" && "detail" in node && typeof node.detail === "number" && "format" in node && typeof node.format === "number" && "mode" in node && typeof node.mode === "string" && "style" in node && typeof node.style === "string" && "text" in node && typeof node.text === "string";
734
736
  }
735
737
 
736
738
  // src/exportToHtml/TextNodeHandler.ts
@@ -813,7 +815,7 @@ var TextNodeHandler = class extends NodeHandler {
813
815
 
814
816
  // src/typeGuards/isSerializedVariableNode.ts
815
817
  function isSerializedVariableNode(node) {
816
- return node?.type === "variable" && typeof node.variableName === "string";
818
+ return node?.type === "variable" && "variableName" in node && typeof node.variableName === "string";
817
819
  }
818
820
 
819
821
  // src/exportToHtml/VariableNodeHandler.ts
@@ -1823,6 +1825,13 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
1823
1825
  const isHeader = node.tagName === "TH";
1824
1826
  const cellNode = createEmptyTableCellNode(isHeader);
1825
1827
  cellNode.headerState = node.tagName === "TH" ? 1 : 0;
1828
+ const colspan = node.getAttribute("colspan");
1829
+ if (colspan) {
1830
+ const colSpanValue = parseInt(colspan, 10);
1831
+ if (!isNaN(colSpanValue) && colSpanValue > 1) {
1832
+ cellNode.colSpan = colSpanValue;
1833
+ }
1834
+ }
1826
1835
  const styleAttr = node.getAttribute("style") || "";
1827
1836
  const width = extractStyleValue(styleAttr, "width", true, "%");
1828
1837
  if (width !== null) {
@@ -1907,8 +1916,20 @@ var TableNodeHandler2 = class extends NodeHandler2 {
1907
1916
  tableNode.children.push(...processedRows);
1908
1917
  });
1909
1918
  }
1919
+ hasColspan(row) {
1920
+ const cells = row.querySelectorAll("th, td");
1921
+ return Array.from(cells).some((cell) => {
1922
+ const colspan = cell.getAttribute("colspan");
1923
+ return colspan && parseInt(colspan, 10) > 1;
1924
+ });
1925
+ }
1910
1926
  findTargetRowForWidths(node) {
1911
- return node.querySelector("thead tr") || node.querySelector("tbody tr") || node.querySelector("tr");
1927
+ const rows = node.querySelectorAll("tr");
1928
+ if (rows.length === 0) return null;
1929
+ for (const row of rows) {
1930
+ if (!this.hasColspan(row)) return row;
1931
+ }
1932
+ return rows[0];
1912
1933
  }
1913
1934
  extractColumnWidths(targetRow, effectiveReferenceWidth) {
1914
1935
  const cells = targetRow.querySelectorAll("th, td");
@@ -1921,11 +1942,28 @@ var TableNodeHandler2 = class extends NodeHandler2 {
1921
1942
  cell,
1922
1943
  effectiveReferenceWidth
1923
1944
  );
1924
- colWidths.push(result.width);
1925
- if (result.width > 0) {
1926
- totalSpecifiedPercent += result.percentEquivalent;
1945
+ const colspan = parseInt(
1946
+ cell.getAttribute("colspan") || "1",
1947
+ 10
1948
+ );
1949
+ if (colspan > 1) {
1950
+ const widthPerColumn = result.width / colspan;
1951
+ const percentPerColumn = result.percentEquivalent / colspan;
1952
+ for (let i = 0; i < colspan; i++) {
1953
+ colWidths.push(Math.round(widthPerColumn));
1954
+ if (result.width > 0) {
1955
+ totalSpecifiedPercent += percentPerColumn;
1956
+ } else {
1957
+ unspecifiedColumns++;
1958
+ }
1959
+ }
1927
1960
  } else {
1928
- unspecifiedColumns++;
1961
+ colWidths.push(result.width);
1962
+ if (result.width > 0) {
1963
+ totalSpecifiedPercent += result.percentEquivalent;
1964
+ } else {
1965
+ unspecifiedColumns++;
1966
+ }
1929
1967
  }
1930
1968
  });
1931
1969
  if (unspecifiedColumns > 0 && totalSpecifiedPercent < 100) {
package/dist/index.mjs CHANGED
@@ -66,12 +66,12 @@ var EssayQuestionNodeHandler = class extends NodeHandler {
66
66
 
67
67
  // src/typeGuards/isSerializedFillInTheBlankQuestionNode.ts
68
68
  function isSerializedFillInTheBlankQuestionNode(node) {
69
- return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "content" in node && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number";
69
+ return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number" && "content" in node;
70
70
  }
71
71
 
72
72
  // src/typeGuards/isSerializedParagraphNode.ts
73
73
  function isSerializedParagraphNode(node) {
74
- return node?.type === "paragraph" && "children" in node && Array.isArray(node.children);
74
+ return node?.type === "paragraph" && "textFormat" in node && typeof node.textFormat === "number" && "textStyle" in node && typeof node.textStyle === "string";
75
75
  }
76
76
 
77
77
  // src/exportToHtml/createHtmlFromNestedNodes.ts
@@ -109,7 +109,7 @@ var FillInTheBlankQuestionNodeHandler = class extends NodeHandler {
109
109
 
110
110
  // src/typeGuards/isSerializedFillInTheBlankSpaceNode.ts
111
111
  function isSerializedFillInTheBlankSpaceNode(node) {
112
- return node?.type === "space" && "id" in node && typeof node.id === "string" && "spaceType" in node && "matches" in node && typeof node.matches === "string";
112
+ return node?.type === "space" && "id" in node && typeof node.id === "string" && "spaceName" in node && typeof node.spaceName === "string" && "matches" in node && typeof node.matches === "string" && "spaceType" in node;
113
113
  }
114
114
 
115
115
  // src/exportToHtml/FillInTheBlankSpaceNodeHandler.ts
@@ -150,7 +150,7 @@ var FillInTheBlankSpaceNodeHandler = class extends NodeHandler {
150
150
 
151
151
  // src/typeGuards/isSerializedFinancialStatementQuestionNode.ts
152
152
  function isSerializedFinancialStatementQuestionNode(node) {
153
- return node?.type === "financial-statement-question" && "id" in node && typeof node.id === "string" && "header" in node && "rows" in node && Array.isArray(node.rows) && "points" in node && typeof node.points === "number";
153
+ return node?.type === "financial-statement-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "header" in node && "columnHeaders" in node && Array.isArray(node.columnHeaders) && "rows" in node && Array.isArray(node.rows) && "distractors" in node && Array.isArray(node.distractors);
154
154
  }
155
155
 
156
156
  // src/exportToHtml/FinancialStatementQuestionNodeHandler.ts
@@ -216,7 +216,7 @@ var FinancialStatementQuestionNodeHandler = class extends NodeHandler {
216
216
 
217
217
  // src/typeGuards/isSerializedHorizontalRuleNode.ts
218
218
  var isSerializedHorizontalRuleNode = (node) => {
219
- return node.type === "horizontalrule";
219
+ return node?.type === "horizontalrule";
220
220
  };
221
221
 
222
222
  // src/exportToHtml/HorizontalRuleNodeHandler.ts
@@ -229,7 +229,7 @@ var HorizontalRuleNodeHandler = class extends NodeHandler {
229
229
 
230
230
  // src/typeGuards/isSerializedImageNode.ts
231
231
  var isSerializedImageNode = (node) => {
232
- return node.type === "image";
232
+ return node?.type === "image" && "altText" in node && typeof node.altText === "string" && "caption" in node && "showCaption" in node && typeof node.showCaption === "boolean" && "src" in node && typeof node.src === "string" && "width" in node && typeof node.width === "string" && "align" in node && typeof node.align === "string" && "showBorder" in node && typeof node.showBorder === "boolean";
233
233
  };
234
234
 
235
235
  // src/exportToHtml/ImageNodeHandler.ts
@@ -248,7 +248,7 @@ var ImageNodeHandler = class extends NodeHandler {
248
248
 
249
249
  // src/typeGuards/isSerializedJournalEntryQuestionNode.ts
250
250
  function isSerializedJournalEntryQuestionNode(node) {
251
- return node?.type === "journal-entry-question" && "id" in node && typeof node.id === "string" && "lineItems" in node && Array.isArray(node.lineItems) && "points" in node && typeof node.points === "number";
251
+ return node?.type === "journal-entry-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "journalType" in node && typeof node.journalType === "string" && "lineItems" in node && Array.isArray(node.lineItems);
252
252
  }
253
253
 
254
254
  // src/exportToHtml/JournalEntryQuestionNodeHandler.ts
@@ -330,7 +330,7 @@ var LineBreakNodeHandler = class extends NodeHandler {
330
330
 
331
331
  // src/typeGuards/isSerializedLinkNode.ts
332
332
  var isSerializedLinkNode = (node) => {
333
- return node.type === "link";
333
+ return node?.type === "link" && "url" in node && typeof node.url === "string";
334
334
  };
335
335
 
336
336
  // src/exportToHtml/LinkNodeHandler.ts
@@ -347,7 +347,7 @@ var LinkNodeHandler = class extends NodeHandler {
347
347
 
348
348
  // src/typeGuards/isSerializedListItemNode.ts
349
349
  var isSerializedListItemNode = (node) => {
350
- return node.type === "listitem";
350
+ return node?.type === "listitem" && "value" in node && typeof node.value === "number";
351
351
  };
352
352
 
353
353
  // src/exportToHtml/ListItemNodeHandler.ts
@@ -370,7 +370,7 @@ var ListItemNodeHandler = class extends NodeHandler {
370
370
 
371
371
  // src/typeGuards/isSerializedListNode.ts
372
372
  var isSerializedListNode = (node) => {
373
- return node !== void 0 && node.type === "list";
373
+ return node?.type === "list" && "listType" in node && typeof node.listType === "string" && "start" in node && typeof node.start === "number" && "tag" in node && typeof node.tag === "string";
374
374
  };
375
375
 
376
376
  // src/exportToHtml/ListNodeHandler.ts
@@ -394,7 +394,7 @@ var ListNodeHandler = class extends NodeHandler {
394
394
 
395
395
  // src/typeGuards/isSerializedMatchingQuestionNode.ts
396
396
  function isSerializedMatchingQuestionNode(node) {
397
- return node?.type === "matching-question" && "id" in node && typeof node.id === "string" && "items" in node && Array.isArray(node.items) && "pointsPerMatch" in node && typeof node.pointsPerMatch === "number";
397
+ return node?.type === "matching-question" && "id" in node && typeof node.id === "string" && "pointsPerMatch" in node && typeof node.pointsPerMatch === "number" && "items" in node && Array.isArray(node.items);
398
398
  }
399
399
 
400
400
  // src/exportToHtml/MatchingQuestionNodeHandler.ts
@@ -434,7 +434,7 @@ var MatchingQuestionNodeHandler = class extends NodeHandler {
434
434
 
435
435
  // src/typeGuards/isSerializedMultipleOptionQuestionNode.ts
436
436
  function isSerializedMultipleOptionQuestionNode(node) {
437
- return node?.type === "multiple-option-question" && "id" in node && typeof node.id === "string" && "options" in node && Array.isArray(node.options) && "questionType" in node && typeof node.questionType === "string" && "points" in node && typeof node.points === "number";
437
+ return node?.type === "multiple-option-question" && "id" in node && typeof node.id === "string" && "questionType" in node && typeof node.questionType === "string" && "points" in node && typeof node.points === "number" && "options" in node && Array.isArray(node.options);
438
438
  }
439
439
 
440
440
  // src/exportToHtml/MultipleOptionQuestionNodeHandler.ts
@@ -503,7 +503,7 @@ function isSerializedShortAnswerQuestionNode(node) {
503
503
 
504
504
  // src/typeGuards/isSerializedTableCellNode.ts
505
505
  function isSerializedTableCellNode(node) {
506
- return node?.type === "tablecell";
506
+ return node?.type === "tablecell" && "headerState" in node && typeof node.headerState === "number";
507
507
  }
508
508
 
509
509
  // src/exportToHtml/ParagraphNodeHandler.ts
@@ -567,7 +567,7 @@ var ShortAnswerQuestionNodeHandler = class extends NodeHandler {
567
567
 
568
568
  // src/typeGuards/isSerializedSimulationQuestionNode.ts
569
569
  function isSerializedSimulationQuestionNode(node) {
570
- return node?.type === "simulation-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "step2Instructions" in node && typeof node.step2Instructions === "string";
570
+ return node?.type === "simulation-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number";
571
571
  }
572
572
 
573
573
  // src/exportToHtml/SimulationQuestionNodeHandler.ts
@@ -583,7 +583,7 @@ var SimulationQuestionNodeHandler = class extends NodeHandler {
583
583
 
584
584
  // src/typeGuards/isSerializedTableRowNode.ts
585
585
  function isSerializedTableRowNode(node) {
586
- return node?.type === "tablerow" && "children" in node && Array.isArray(node.children);
586
+ return node?.type === "tablerow";
587
587
  }
588
588
 
589
589
  // src/exportToHtml/TableCellNodeHandler.ts
@@ -602,9 +602,10 @@ var TableCellNodeHandler = class extends NodeHandler {
602
602
  }
603
603
  }
604
604
  }
605
- if (metadata?.colWidthPixels && cellIndex >= 0 && cellIndex < metadata.colWidthPixels.length) {
605
+ const hasColspan = tableCellNode.colSpan && tableCellNode.colSpan > 1;
606
+ if (!hasColspan && metadata?.colWidthPixels && cellIndex >= 0 && cellIndex < metadata.colWidthPixels.length) {
606
607
  styles.push(`width: ${metadata.colWidthPixels[cellIndex]}px;`);
607
- } else if (tableCellNode.width) {
608
+ } else if (!hasColspan && tableCellNode.width) {
608
609
  styles.push(`width: ${tableCellNode.width}px;`);
609
610
  }
610
611
  if (tableCellNode.backgroundColor) {
@@ -617,13 +618,14 @@ var TableCellNodeHandler = class extends NodeHandler {
617
618
  }
618
619
  const styleAttr = styles.length > 0 ? ` style="${styles.join(" ")}"` : "";
619
620
  const tag = tableCellNode.headerState > 0 ? "th" : "td";
620
- return `<${tag}${styleAttr}>${createHtmlFromNestedNodes(tableCellNode.children, { parentNode: tableCellNode })}</${tag}>`;
621
+ const colspanAttr = tableCellNode.colSpan && tableCellNode.colSpan > 1 ? ` colspan="${tableCellNode.colSpan}"` : "";
622
+ return `<${tag}${styleAttr}${colspanAttr}>${createHtmlFromNestedNodes(tableCellNode.children, { parentNode: tableCellNode })}</${tag}>`;
621
623
  }
622
624
  };
623
625
 
624
626
  // src/typeGuards/isSerializedTableNode.ts
625
627
  function isSerializedTableNode(node) {
626
- return node?.type === "table" && "children" in node && Array.isArray(node.children);
628
+ return node?.type === "table";
627
629
  }
628
630
 
629
631
  // src/exportToHtml/TableNodeHandler.ts
@@ -703,7 +705,7 @@ var TableRowNodeHandler = class extends NodeHandler {
703
705
 
704
706
  // src/typeGuards/isSerializedTextNode.ts
705
707
  function isSerializedTextNode(node) {
706
- return node?.type === "text" && "text" in node && typeof node.text === "string";
708
+ return node?.type === "text" && "detail" in node && typeof node.detail === "number" && "format" in node && typeof node.format === "number" && "mode" in node && typeof node.mode === "string" && "style" in node && typeof node.style === "string" && "text" in node && typeof node.text === "string";
707
709
  }
708
710
 
709
711
  // src/exportToHtml/TextNodeHandler.ts
@@ -786,7 +788,7 @@ var TextNodeHandler = class extends NodeHandler {
786
788
 
787
789
  // src/typeGuards/isSerializedVariableNode.ts
788
790
  function isSerializedVariableNode(node) {
789
- return node?.type === "variable" && typeof node.variableName === "string";
791
+ return node?.type === "variable" && "variableName" in node && typeof node.variableName === "string";
790
792
  }
791
793
 
792
794
  // src/exportToHtml/VariableNodeHandler.ts
@@ -1796,6 +1798,13 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
1796
1798
  const isHeader = node.tagName === "TH";
1797
1799
  const cellNode = createEmptyTableCellNode(isHeader);
1798
1800
  cellNode.headerState = node.tagName === "TH" ? 1 : 0;
1801
+ const colspan = node.getAttribute("colspan");
1802
+ if (colspan) {
1803
+ const colSpanValue = parseInt(colspan, 10);
1804
+ if (!isNaN(colSpanValue) && colSpanValue > 1) {
1805
+ cellNode.colSpan = colSpanValue;
1806
+ }
1807
+ }
1799
1808
  const styleAttr = node.getAttribute("style") || "";
1800
1809
  const width = extractStyleValue(styleAttr, "width", true, "%");
1801
1810
  if (width !== null) {
@@ -1880,8 +1889,20 @@ var TableNodeHandler2 = class extends NodeHandler2 {
1880
1889
  tableNode.children.push(...processedRows);
1881
1890
  });
1882
1891
  }
1892
+ hasColspan(row) {
1893
+ const cells = row.querySelectorAll("th, td");
1894
+ return Array.from(cells).some((cell) => {
1895
+ const colspan = cell.getAttribute("colspan");
1896
+ return colspan && parseInt(colspan, 10) > 1;
1897
+ });
1898
+ }
1883
1899
  findTargetRowForWidths(node) {
1884
- return node.querySelector("thead tr") || node.querySelector("tbody tr") || node.querySelector("tr");
1900
+ const rows = node.querySelectorAll("tr");
1901
+ if (rows.length === 0) return null;
1902
+ for (const row of rows) {
1903
+ if (!this.hasColspan(row)) return row;
1904
+ }
1905
+ return rows[0];
1885
1906
  }
1886
1907
  extractColumnWidths(targetRow, effectiveReferenceWidth) {
1887
1908
  const cells = targetRow.querySelectorAll("th, td");
@@ -1894,11 +1915,28 @@ var TableNodeHandler2 = class extends NodeHandler2 {
1894
1915
  cell,
1895
1916
  effectiveReferenceWidth
1896
1917
  );
1897
- colWidths.push(result.width);
1898
- if (result.width > 0) {
1899
- totalSpecifiedPercent += result.percentEquivalent;
1918
+ const colspan = parseInt(
1919
+ cell.getAttribute("colspan") || "1",
1920
+ 10
1921
+ );
1922
+ if (colspan > 1) {
1923
+ const widthPerColumn = result.width / colspan;
1924
+ const percentPerColumn = result.percentEquivalent / colspan;
1925
+ for (let i = 0; i < colspan; i++) {
1926
+ colWidths.push(Math.round(widthPerColumn));
1927
+ if (result.width > 0) {
1928
+ totalSpecifiedPercent += percentPerColumn;
1929
+ } else {
1930
+ unspecifiedColumns++;
1931
+ }
1932
+ }
1900
1933
  } else {
1901
- unspecifiedColumns++;
1934
+ colWidths.push(result.width);
1935
+ if (result.width > 0) {
1936
+ totalSpecifiedPercent += result.percentEquivalent;
1937
+ } else {
1938
+ unspecifiedColumns++;
1939
+ }
1902
1940
  }
1903
1941
  });
1904
1942
  if (unspecifiedColumns > 0 && totalSpecifiedPercent < 100) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@examind/block-sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "@comment version": [
5
5
  "Don't specify package version here. It will be injected by publish workflow."
6
6
  ],