@examind/block-sdk 0.1.28 → 0.1.30

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.
Files changed (3) hide show
  1. package/dist/index.js +145 -114
  2. package/dist/index.mjs +140 -109
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -346,9 +346,9 @@ var NodeHandlerChainBuilder = class {
346
346
  }
347
347
  };
348
348
 
349
- // src/typeGuards/isSerializedEssayQuestionNode.ts
350
- function isSerializedEssayQuestionNode(node) {
351
- return node?.type === "essay-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "maxWords" in node && typeof node.maxWords === "number" && "hideChat" in node && typeof node.hideChat === "boolean";
349
+ // src/typeGuards/isSerializedCustomQuestionNode.ts
350
+ function isSerializedCustomQuestionNode(node) {
351
+ return node?.type === "custom-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "name" in node && typeof node.name === "string" && "data" in node && typeof node.data === "string";
352
352
  }
353
353
 
354
354
  // src/exportToHtml/types.ts
@@ -371,6 +371,19 @@ var NodeHandler = class {
371
371
  }
372
372
  };
373
373
 
374
+ // src/exportToHtml/CustomQuestionNodeHandler.ts
375
+ var CustomQuestionNodeHandler = class extends NodeHandler {
376
+ processNode(node) {
377
+ if (!isSerializedCustomQuestionNode(node)) return null;
378
+ return `<x-custom id="${node.id}" data-x-prompt data-x-points="${node.points}" data-x-name="${node.name}"></x-custom>`;
379
+ }
380
+ };
381
+
382
+ // src/typeGuards/isSerializedEssayQuestionNode.ts
383
+ function isSerializedEssayQuestionNode(node) {
384
+ return node?.type === "essay-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "maxWords" in node && typeof node.maxWords === "number" && "hideChat" in node && typeof node.hideChat === "boolean";
385
+ }
386
+
374
387
  // src/exportToHtml/EssayQuestionNodeHandler.ts
375
388
  var EssayQuestionNodeHandler = class extends NodeHandler {
376
389
  processNode(node) {
@@ -1213,7 +1226,7 @@ var VariableNodeHandler = class extends NodeHandler {
1213
1226
 
1214
1227
  // src/exportToHtml/traverse.ts
1215
1228
  var builder = new NodeHandlerChainBuilder();
1216
- var nodeHandlerChain = builder.addHandler(EssayQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
1229
+ var nodeHandlerChain = builder.addHandler(CustomQuestionNodeHandler).addHandler(EssayQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
1217
1230
  var traverse = (node, metadata) => {
1218
1231
  return nodeHandlerChain.handle(node, metadata);
1219
1232
  };
@@ -1232,7 +1245,7 @@ function exportToHtml(editorState) {
1232
1245
  }
1233
1246
 
1234
1247
  // src/importFromHtml/index.ts
1235
- var import_node_html_parser27 = require("node-html-parser");
1248
+ var import_node_html_parser28 = require("node-html-parser");
1236
1249
 
1237
1250
  // src/importFromHtml/createEmptyParagraphNode.ts
1238
1251
  function createEmptyParagraphNode(format = "") {
@@ -1248,11 +1261,59 @@ function createEmptyParagraphNode(format = "") {
1248
1261
  };
1249
1262
  }
1250
1263
 
1264
+ // src/importFromHtml/CustomQuestionNodeHandler.ts
1265
+ var import_node_html_parser = require("node-html-parser");
1266
+
1267
+ // src/importFromHtml/types.ts
1268
+ var NodeHandler2 = class {
1269
+ constructor() {
1270
+ this.nextHandler = null;
1271
+ }
1272
+ getChildNodesTextContent(childNodes) {
1273
+ return childNodes.reduce((acc, item) => {
1274
+ const text = item.textContent || "";
1275
+ return acc + text.trim() + " ";
1276
+ }, "").trimEnd();
1277
+ }
1278
+ setNext(handler) {
1279
+ this.nextHandler = handler;
1280
+ return handler;
1281
+ }
1282
+ handle(node) {
1283
+ const result = this.processNode(node);
1284
+ if (result) {
1285
+ return result;
1286
+ } else if (this.nextHandler) {
1287
+ return this.nextHandler.handle(node);
1288
+ }
1289
+ return null;
1290
+ }
1291
+ };
1292
+
1293
+ // src/importFromHtml/CustomQuestionNodeHandler.ts
1294
+ var TAG_X_CUSTOM = "x-custom";
1295
+ var CustomQuestionNodeHandler2 = class extends NodeHandler2 {
1296
+ processNode(node) {
1297
+ if (!(node instanceof import_node_html_parser.HTMLElement) || node.tagName !== TAG_X_CUSTOM.toUpperCase()) {
1298
+ return null;
1299
+ }
1300
+ const jsonNode = {
1301
+ id: node.getAttribute("id") || "",
1302
+ points: Number(node.getAttribute("data-x-points") || 1),
1303
+ name: node.getAttribute("data-x-name") || "",
1304
+ data: "",
1305
+ type: "custom-question",
1306
+ version: 1
1307
+ };
1308
+ return jsonNode;
1309
+ }
1310
+ };
1311
+
1251
1312
  // src/importFromHtml/DivNodeHandler.ts
1252
- var import_node_html_parser2 = require("node-html-parser");
1313
+ var import_node_html_parser3 = require("node-html-parser");
1253
1314
 
1254
1315
  // src/importFromHtml/createNestedNodesFromHtml.ts
1255
- var import_node_html_parser = require("node-html-parser");
1316
+ var import_node_html_parser2 = require("node-html-parser");
1256
1317
  var wrapInlinesInParagraph = (inlineNodes, format = "") => {
1257
1318
  const paragraph = createEmptyParagraphNode(format);
1258
1319
  paragraph.children = inlineNodes;
@@ -1278,9 +1339,9 @@ var extractFormatFromStyle = (styleAttribute) => {
1278
1339
  return "";
1279
1340
  };
1280
1341
  var createNestedNodesFromHtml = (node) => {
1281
- const parentStyleAttribute = node instanceof import_node_html_parser.HTMLElement ? node.getAttribute("style") : null;
1342
+ const parentStyleAttribute = node instanceof import_node_html_parser2.HTMLElement ? node.getAttribute("style") : null;
1282
1343
  const format = extractFormatFromStyle(parentStyleAttribute);
1283
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser.HTMLElement && node.childNodes[0].tagName === "BR") {
1344
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser2.HTMLElement && node.childNodes[0].tagName === "BR") {
1284
1345
  return [createEmptyParagraphNode(format)];
1285
1346
  }
1286
1347
  const results = [];
@@ -1416,36 +1477,10 @@ function processImageNodeContainer(node) {
1416
1477
  ];
1417
1478
  }
1418
1479
 
1419
- // src/importFromHtml/types.ts
1420
- var NodeHandler2 = class {
1421
- constructor() {
1422
- this.nextHandler = null;
1423
- }
1424
- getChildNodesTextContent(childNodes) {
1425
- return childNodes.reduce((acc, item) => {
1426
- const text = item.textContent || "";
1427
- return acc + text.trim() + " ";
1428
- }, "").trimEnd();
1429
- }
1430
- setNext(handler) {
1431
- this.nextHandler = handler;
1432
- return handler;
1433
- }
1434
- handle(node) {
1435
- const result = this.processNode(node);
1436
- if (result) {
1437
- return result;
1438
- } else if (this.nextHandler) {
1439
- return this.nextHandler.handle(node);
1440
- }
1441
- return null;
1442
- }
1443
- };
1444
-
1445
1480
  // src/importFromHtml/DivNodeHandler.ts
1446
1481
  var DivNodeHandler = class extends NodeHandler2 {
1447
1482
  isHtmlDivElement(node) {
1448
- return node instanceof import_node_html_parser2.HTMLElement && node.tagName === "DIV";
1483
+ return node instanceof import_node_html_parser3.HTMLElement && node.tagName === "DIV";
1449
1484
  }
1450
1485
  processNode(node) {
1451
1486
  if (!this.isHtmlDivElement(node)) {
@@ -1460,12 +1495,12 @@ var DivNodeHandler = class extends NodeHandler2 {
1460
1495
 
1461
1496
  // src/importFromHtml/EssayQuestionNodeHandler.ts
1462
1497
  var import_nanoid = require("nanoid");
1463
- var import_node_html_parser3 = require("node-html-parser");
1498
+ var import_node_html_parser4 = require("node-html-parser");
1464
1499
  var TAG_X_ESSAY = "x-essay";
1465
1500
  var TAG_X_SYSTEM_MESSAGE = "x-ai-system-message";
1466
1501
  var EssayQuestionNodeHandler2 = class extends NodeHandler2 {
1467
1502
  processNode(node) {
1468
- if (!(node instanceof import_node_html_parser3.HTMLElement) || node.tagName !== TAG_X_ESSAY.toUpperCase()) {
1503
+ if (!(node instanceof import_node_html_parser4.HTMLElement) || node.tagName !== TAG_X_ESSAY.toUpperCase()) {
1469
1504
  return null;
1470
1505
  }
1471
1506
  const jsonNode = {
@@ -1491,7 +1526,7 @@ var EssayQuestionNodeHandler2 = class extends NodeHandler2 {
1491
1526
 
1492
1527
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1493
1528
  var import_nanoid2 = require("nanoid");
1494
- var import_node_html_parser4 = require("node-html-parser");
1529
+ var import_node_html_parser5 = require("node-html-parser");
1495
1530
 
1496
1531
  // src/importFromHtml/createNestedEditorFromHtml.ts
1497
1532
  function createNestedEditorFromHtml(node) {
@@ -1512,7 +1547,7 @@ function createNestedEditorFromHtml(node) {
1512
1547
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1513
1548
  var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1514
1549
  processNode(node) {
1515
- if (!(node instanceof import_node_html_parser4.HTMLElement) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1550
+ if (!(node instanceof import_node_html_parser5.HTMLElement) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1516
1551
  return null;
1517
1552
  const jsonNode = {
1518
1553
  id: node.getAttribute("id") ?? (0, import_nanoid2.nanoid)(),
@@ -1529,7 +1564,7 @@ var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1529
1564
 
1530
1565
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1531
1566
  var import_nanoid3 = require("nanoid");
1532
- var import_node_html_parser5 = require("node-html-parser");
1567
+ var import_node_html_parser6 = require("node-html-parser");
1533
1568
 
1534
1569
  // src/importFromHtml/parseErrorToleranceAttribute.ts
1535
1570
  function parseErrorToleranceAttribute(attr) {
@@ -1541,7 +1576,7 @@ function parseErrorToleranceAttribute(attr) {
1541
1576
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1542
1577
  var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1543
1578
  processNode(node) {
1544
- if (!(node instanceof import_node_html_parser5.HTMLElement) || node.tagName !== "x-space".toUpperCase())
1579
+ if (!(node instanceof import_node_html_parser6.HTMLElement) || node.tagName !== "x-space".toUpperCase())
1545
1580
  return null;
1546
1581
  const spaceTypeAttr = node.getAttribute("data-x-type");
1547
1582
  const spaceType = spaceTypeAttr === "Text" || spaceTypeAttr === "Number" || spaceTypeAttr === "Dropdown" ? spaceTypeAttr : "Text";
@@ -1591,7 +1626,7 @@ var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1591
1626
 
1592
1627
  // src/importFromHtml/FinancialStatementQuestionNodeHandler.ts
1593
1628
  var import_nanoid4 = require("nanoid");
1594
- var import_node_html_parser6 = require("node-html-parser");
1629
+ var import_node_html_parser7 = require("node-html-parser");
1595
1630
  var TAG_X_FINANCIAL_STATEMENT = "x-financial-statement";
1596
1631
  var TAG_X_HEADER = "x-header";
1597
1632
  var TAG_X_ROWS = "x-rows";
@@ -1603,7 +1638,7 @@ var TAG_X_ENTRY = "x-entry";
1603
1638
  var TAG_X_AMOUNT = "x-amount";
1604
1639
  var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1605
1640
  processNode(node) {
1606
- if (!(node instanceof import_node_html_parser6.HTMLElement) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1641
+ if (!(node instanceof import_node_html_parser7.HTMLElement) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1607
1642
  return null;
1608
1643
  }
1609
1644
  const headerElement = node.querySelector(TAG_X_HEADER);
@@ -1618,7 +1653,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1618
1653
  version: 1
1619
1654
  };
1620
1655
  node.childNodes.forEach((child) => {
1621
- if (!(child instanceof import_node_html_parser6.HTMLElement)) return;
1656
+ if (!(child instanceof import_node_html_parser7.HTMLElement)) return;
1622
1657
  if (child.tagName === TAG_X_DISTRACTORS.toUpperCase()) {
1623
1658
  this.processDistractorsNode(child, jsonNode);
1624
1659
  } else if (child.tagName === TAG_X_ROWS.toUpperCase()) {
@@ -1629,7 +1664,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1629
1664
  }
1630
1665
  processDistractorsNode(distractorsNode, jsonNode) {
1631
1666
  for (const distractorsChild of distractorsNode.childNodes) {
1632
- if (!(distractorsChild instanceof import_node_html_parser6.HTMLElement)) continue;
1667
+ if (!(distractorsChild instanceof import_node_html_parser7.HTMLElement)) continue;
1633
1668
  if (distractorsChild.tagName !== TAG_X_DISTRACTOR.toUpperCase())
1634
1669
  continue;
1635
1670
  jsonNode.distractors.push({
@@ -1650,7 +1685,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1650
1685
  const contentDiv = headerElement.querySelector(
1651
1686
  'div > div:not([style*="display:flex"])'
1652
1687
  );
1653
- if (contentDiv && contentDiv instanceof import_node_html_parser6.HTMLElement) {
1688
+ if (contentDiv && contentDiv instanceof import_node_html_parser7.HTMLElement) {
1654
1689
  const contentDivClone = contentDiv.clone();
1655
1690
  contentDivClone.setAttribute("style", "text-align: left;");
1656
1691
  return createNestedEditorFromHtml(contentDivClone);
@@ -1670,7 +1705,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1670
1705
  }
1671
1706
  processRowsNode(rowsNode, jsonNode) {
1672
1707
  for (const rowsChild of rowsNode.childNodes) {
1673
- if (!(rowsChild instanceof import_node_html_parser6.HTMLElement)) continue;
1708
+ if (!(rowsChild instanceof import_node_html_parser7.HTMLElement)) continue;
1674
1709
  if (rowsChild.tagName === TAG_X_HEADING.toUpperCase()) {
1675
1710
  this.processHeadingRow(rowsChild, jsonNode);
1676
1711
  } else if (rowsChild.tagName === TAG_X_LINE.toUpperCase()) {
@@ -1704,7 +1739,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1704
1739
  };
1705
1740
 
1706
1741
  // src/importFromHtml/FormattedNodeHandler.ts
1707
- var import_node_html_parser7 = require("node-html-parser");
1742
+ var import_node_html_parser8 = require("node-html-parser");
1708
1743
  var IS_BOLD2 = 1;
1709
1744
  var IS_ITALIC2 = 1 << 1;
1710
1745
  var IS_STRIKETHROUGH2 = 1 << 2;
@@ -1744,7 +1779,7 @@ function formatToProps(format) {
1744
1779
  }
1745
1780
  var FormattedNodeHandler = class extends NodeHandler2 {
1746
1781
  processNode(node) {
1747
- if (!(node instanceof import_node_html_parser7.HTMLElement)) return null;
1782
+ if (!(node instanceof import_node_html_parser8.HTMLElement)) return null;
1748
1783
  const tagName = node.tagName;
1749
1784
  if (!tagName || !(tagName in TAG_TO_FORMAT)) return null;
1750
1785
  const formatFlag = TAG_TO_FORMAT[tagName];
@@ -1779,11 +1814,11 @@ var FormattedNodeHandler = class extends NodeHandler2 {
1779
1814
  };
1780
1815
 
1781
1816
  // src/importFromHtml/HorizontalRuleNodeHandler.ts
1782
- var import_node_html_parser8 = require("node-html-parser");
1817
+ var import_node_html_parser9 = require("node-html-parser");
1783
1818
  var TAG_HR = "hr";
1784
1819
  var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1785
1820
  processNode(node) {
1786
- if (!(node instanceof import_node_html_parser8.HTMLElement) || node.tagName !== TAG_HR.toUpperCase()) {
1821
+ if (!(node instanceof import_node_html_parser9.HTMLElement) || node.tagName !== TAG_HR.toUpperCase()) {
1787
1822
  return null;
1788
1823
  }
1789
1824
  const horizontalRuleNode = {
@@ -1795,11 +1830,11 @@ var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1795
1830
  };
1796
1831
 
1797
1832
  // src/importFromHtml/ImageNodeHandler.ts
1798
- var import_node_html_parser9 = require("node-html-parser");
1833
+ var import_node_html_parser10 = require("node-html-parser");
1799
1834
  var TAG_IMG = "img";
1800
1835
  var ImageNodeHandler2 = class extends NodeHandler2 {
1801
1836
  processNode(node) {
1802
- if (!(node instanceof import_node_html_parser9.HTMLElement) || node.tagName !== TAG_IMG.toUpperCase()) {
1837
+ if (!(node instanceof import_node_html_parser10.HTMLElement) || node.tagName !== TAG_IMG.toUpperCase()) {
1803
1838
  return null;
1804
1839
  }
1805
1840
  return createImageNode(
@@ -1815,11 +1850,11 @@ var ImageNodeHandler2 = class extends NodeHandler2 {
1815
1850
 
1816
1851
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1817
1852
  var import_nanoid6 = require("nanoid");
1818
- var import_node_html_parser11 = require("node-html-parser");
1853
+ var import_node_html_parser12 = require("node-html-parser");
1819
1854
 
1820
1855
  // src/importFromHtml/createOnePerLineDistractorNode.ts
1821
1856
  var import_nanoid5 = require("nanoid");
1822
- var import_node_html_parser10 = require("node-html-parser");
1857
+ var import_node_html_parser11 = require("node-html-parser");
1823
1858
  function extractDistractorId(id) {
1824
1859
  if (!id) return null;
1825
1860
  const parts = id.split("|");
@@ -1832,7 +1867,7 @@ var createOnePerLineDistractorNode = (node) => {
1832
1867
  distractorEditor.editorState.root.children = [];
1833
1868
  let distractorId = null;
1834
1869
  distractors.forEach((distractor) => {
1835
- if (!(distractor instanceof import_node_html_parser10.HTMLElement)) return;
1870
+ if (!(distractor instanceof import_node_html_parser11.HTMLElement)) return;
1836
1871
  distractorId = distractorId ?? extractDistractorId(distractor.getAttribute("id"));
1837
1872
  distractorEditor.editorState.root.children.push(
1838
1873
  ...createNestedNodesFromHtml(distractor)
@@ -1850,7 +1885,7 @@ var createOnePerLineDistractorNode = (node) => {
1850
1885
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1851
1886
  var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1852
1887
  processNode(node) {
1853
- if (!(node instanceof import_node_html_parser11.HTMLElement) || node.tagName !== "x-journal-entry".toUpperCase())
1888
+ if (!(node instanceof import_node_html_parser12.HTMLElement) || node.tagName !== "x-journal-entry".toUpperCase())
1854
1889
  return null;
1855
1890
  const jsonNode = {
1856
1891
  id: node.getAttribute("id") ?? (0, import_nanoid6.nanoid)(),
@@ -1865,7 +1900,7 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1865
1900
  };
1866
1901
  const lineItems = node.querySelectorAll("x-line-item");
1867
1902
  lineItems.forEach((lineItem) => {
1868
- if (!(lineItem instanceof import_node_html_parser11.HTMLElement)) return;
1903
+ if (!(lineItem instanceof import_node_html_parser12.HTMLElement)) return;
1869
1904
  const accountElement = lineItem.querySelector("x-account");
1870
1905
  const debitElement = lineItem.querySelector("x-debit");
1871
1906
  const creditElement = lineItem.querySelector("x-credit");
@@ -1894,10 +1929,10 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1894
1929
  };
1895
1930
 
1896
1931
  // src/importFromHtml/LineBreakNodeHandler.ts
1897
- var import_node_html_parser12 = require("node-html-parser");
1932
+ var import_node_html_parser13 = require("node-html-parser");
1898
1933
  var LineBreakNodeHandler2 = class extends NodeHandler2 {
1899
1934
  processNode(node) {
1900
- if (!(node instanceof import_node_html_parser12.HTMLElement)) return null;
1935
+ if (!(node instanceof import_node_html_parser13.HTMLElement)) return null;
1901
1936
  if (node.tagName !== "BR") return null;
1902
1937
  return {
1903
1938
  type: "linebreak",
@@ -1907,11 +1942,11 @@ var LineBreakNodeHandler2 = class extends NodeHandler2 {
1907
1942
  };
1908
1943
 
1909
1944
  // src/importFromHtml/LinkNodeHandler.ts
1910
- var import_node_html_parser13 = require("node-html-parser");
1945
+ var import_node_html_parser14 = require("node-html-parser");
1911
1946
  var TAG_A = "a";
1912
1947
  var LinkNodeHandler2 = class extends NodeHandler2 {
1913
1948
  processNode(node) {
1914
- if (!(node instanceof import_node_html_parser13.HTMLElement) || node.tagName !== TAG_A.toUpperCase()) {
1949
+ if (!(node instanceof import_node_html_parser14.HTMLElement) || node.tagName !== TAG_A.toUpperCase()) {
1915
1950
  return null;
1916
1951
  }
1917
1952
  const url = node.getAttribute("href") || "";
@@ -1940,10 +1975,10 @@ var LinkNodeHandler2 = class extends NodeHandler2 {
1940
1975
  };
1941
1976
 
1942
1977
  // src/importFromHtml/ListItemNodeHandler.ts
1943
- var import_node_html_parser14 = require("node-html-parser");
1978
+ var import_node_html_parser15 = require("node-html-parser");
1944
1979
  var ListItemNodeHandler2 = class extends NodeHandler2 {
1945
1980
  processNode(node) {
1946
- if (!(node instanceof import_node_html_parser14.HTMLElement)) return null;
1981
+ if (!(node instanceof import_node_html_parser15.HTMLElement)) return null;
1947
1982
  if (node.tagName !== "LI") return null;
1948
1983
  const jsonNode = {
1949
1984
  type: "listitem",
@@ -1964,10 +1999,10 @@ var ListItemNodeHandler2 = class extends NodeHandler2 {
1964
1999
  };
1965
2000
 
1966
2001
  // src/importFromHtml/ListNodeHandler.ts
1967
- var import_node_html_parser15 = require("node-html-parser");
2002
+ var import_node_html_parser16 = require("node-html-parser");
1968
2003
  var ListNodeHandler2 = class extends NodeHandler2 {
1969
2004
  processNode(node) {
1970
- if (!(node instanceof import_node_html_parser15.HTMLElement)) return null;
2005
+ if (!(node instanceof import_node_html_parser16.HTMLElement)) return null;
1971
2006
  if (node.tagName !== "UL" && node.tagName !== "OL") return null;
1972
2007
  const tag = node.tagName.toLowerCase();
1973
2008
  const listType = tag === "ol" ? "number" : "bullet";
@@ -1985,7 +2020,7 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1985
2020
  };
1986
2021
  let itemIndex = 1;
1987
2022
  node.childNodes.forEach((child) => {
1988
- if (child instanceof import_node_html_parser15.HTMLElement && child.tagName === "LI") {
2023
+ if (child instanceof import_node_html_parser16.HTMLElement && child.tagName === "LI") {
1989
2024
  const listItemNode = {
1990
2025
  type: "listitem",
1991
2026
  version: 1,
@@ -2010,10 +2045,10 @@ var ListNodeHandler2 = class extends NodeHandler2 {
2010
2045
 
2011
2046
  // src/importFromHtml/MatchingQuestionNodeHandler.ts
2012
2047
  var import_nanoid7 = require("nanoid");
2013
- var import_node_html_parser16 = require("node-html-parser");
2048
+ var import_node_html_parser17 = require("node-html-parser");
2014
2049
  var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
2015
2050
  processNode(node) {
2016
- if (!(node instanceof import_node_html_parser16.HTMLElement) || node.tagName !== "x-matching".toUpperCase())
2051
+ if (!(node instanceof import_node_html_parser17.HTMLElement) || node.tagName !== "x-matching".toUpperCase())
2017
2052
  return null;
2018
2053
  const jsonNode = {
2019
2054
  id: node.getAttribute("id") ?? (0, import_nanoid7.nanoid)(),
@@ -2026,7 +2061,7 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
2026
2061
  };
2027
2062
  const matches = node.querySelectorAll("x-match");
2028
2063
  matches.forEach((match) => {
2029
- if (!(match instanceof import_node_html_parser16.HTMLElement)) return;
2064
+ if (!(match instanceof import_node_html_parser17.HTMLElement)) return;
2030
2065
  const premise = match.querySelector("x-premise");
2031
2066
  const option = match.querySelector("x-option");
2032
2067
  if (!premise || !option) return;
@@ -2049,10 +2084,10 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
2049
2084
 
2050
2085
  // src/importFromHtml/MultipleOptionQuestionNodeHandler.ts
2051
2086
  var import_nanoid8 = require("nanoid");
2052
- var import_node_html_parser17 = require("node-html-parser");
2087
+ var import_node_html_parser18 = require("node-html-parser");
2053
2088
  var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
2054
2089
  processNode(node) {
2055
- if (!(node instanceof import_node_html_parser17.HTMLElement)) return null;
2090
+ if (!(node instanceof import_node_html_parser18.HTMLElement)) return null;
2056
2091
  if (node.tagName === "x-multiple-choice".toUpperCase())
2057
2092
  return this.processMultipleChoiceNode(node);
2058
2093
  else if (node.tagName === "x-multiple-answers".toUpperCase())
@@ -2092,7 +2127,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
2092
2127
  processOptions(node, jsonNode) {
2093
2128
  const childNodes = node.childNodes;
2094
2129
  childNodes.forEach((child) => {
2095
- if (!(child instanceof import_node_html_parser17.HTMLElement)) return;
2130
+ if (!(child instanceof import_node_html_parser18.HTMLElement)) return;
2096
2131
  if (child.tagName !== "x-option".toUpperCase()) return;
2097
2132
  jsonNode.options.push({
2098
2133
  id: child.getAttribute("id") ?? (0, import_nanoid8.nanoid)(),
@@ -2104,7 +2139,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
2104
2139
  };
2105
2140
 
2106
2141
  // src/importFromHtml/ParagraphNodeHandler.ts
2107
- var import_node_html_parser18 = require("node-html-parser");
2142
+ var import_node_html_parser19 = require("node-html-parser");
2108
2143
  var TEXT_ALIGN_TO_FORMAT = {
2109
2144
  center: "center",
2110
2145
  end: "end",
@@ -2127,25 +2162,25 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
2127
2162
  return "";
2128
2163
  }
2129
2164
  processImageNode(node) {
2130
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser18.HTMLElement && node.childNodes[0].tagName === "IMG") {
2165
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser19.HTMLElement && node.childNodes[0].tagName === "IMG") {
2131
2166
  return traverse2(node.childNodes[0]);
2132
2167
  }
2133
2168
  return null;
2134
2169
  }
2135
2170
  processSpanImageNode(node) {
2136
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser18.HTMLElement && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof import_node_html_parser18.HTMLElement && node.childNodes[0].childNodes[0].tagName === "IMG") {
2171
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser19.HTMLElement && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof import_node_html_parser19.HTMLElement && node.childNodes[0].childNodes[0].tagName === "IMG") {
2137
2172
  return traverse2(node.childNodes[0].childNodes[0]);
2138
2173
  }
2139
2174
  return null;
2140
2175
  }
2141
2176
  processNode(node) {
2142
- if (!(node instanceof import_node_html_parser18.HTMLElement)) return null;
2177
+ if (!(node instanceof import_node_html_parser19.HTMLElement)) return null;
2143
2178
  if (node.tagName !== "P") return null;
2144
2179
  const imageNode = this.processImageNode(node) ?? this.processSpanImageNode(node);
2145
2180
  if (imageNode) return imageNode;
2146
2181
  const jsonNode = createEmptyParagraphNode();
2147
2182
  jsonNode.format = this.extractTextAlignment(node);
2148
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser18.HTMLElement && node.childNodes[0].tagName === "BR")
2183
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser19.HTMLElement && node.childNodes[0].tagName === "BR")
2149
2184
  return jsonNode;
2150
2185
  node.childNodes.forEach((child) => {
2151
2186
  const processedChildren = traverse2(child);
@@ -2157,10 +2192,10 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
2157
2192
 
2158
2193
  // src/importFromHtml/ShortAnswerQuestionNodeHandler.ts
2159
2194
  var import_nanoid9 = require("nanoid");
2160
- var import_node_html_parser19 = require("node-html-parser");
2195
+ var import_node_html_parser20 = require("node-html-parser");
2161
2196
  var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
2162
2197
  processNode(node) {
2163
- if (!(node instanceof import_node_html_parser19.HTMLElement) || node.tagName !== "x-short-answer".toUpperCase())
2198
+ if (!(node instanceof import_node_html_parser20.HTMLElement) || node.tagName !== "x-short-answer".toUpperCase())
2164
2199
  return null;
2165
2200
  return {
2166
2201
  id: node.getAttribute("id") ?? (0, import_nanoid9.nanoid)(),
@@ -2176,13 +2211,13 @@ var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
2176
2211
  };
2177
2212
 
2178
2213
  // src/importFromHtml/SimulationQuestionNodeHandler.ts
2179
- var import_node_html_parser20 = require("node-html-parser");
2214
+ var import_node_html_parser21 = require("node-html-parser");
2180
2215
  var TAG_X_SIMULATION = "x-simulation";
2181
2216
  var TAG_X_SYSTEM_MESSAGE2 = "x-ai-system-message";
2182
2217
  var TAG_X_STEP2_INSTRUCTIONS = "x-step2-instructions";
2183
2218
  var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
2184
2219
  processNode(node) {
2185
- if (!(node instanceof import_node_html_parser20.HTMLElement) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2220
+ if (!(node instanceof import_node_html_parser21.HTMLElement) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2186
2221
  return null;
2187
2222
  }
2188
2223
  const jsonNode = {
@@ -2209,11 +2244,11 @@ var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
2209
2244
  };
2210
2245
 
2211
2246
  // src/importFromHtml/SpanNodeHandler.ts
2212
- var import_node_html_parser21 = require("node-html-parser");
2213
- var TextNode = import_node_html_parser21.parse.TextNode;
2247
+ var import_node_html_parser22 = require("node-html-parser");
2248
+ var TextNode = import_node_html_parser22.parse.TextNode;
2214
2249
  var SpanNodeHandler = class extends NodeHandler2 {
2215
2250
  processNode(node) {
2216
- if (!(node instanceof import_node_html_parser21.HTMLElement) || node.tagName !== "SPAN")
2251
+ if (!(node instanceof import_node_html_parser22.HTMLElement) || node.tagName !== "SPAN")
2217
2252
  return null;
2218
2253
  const styleAttr = node.getAttribute("style") || "";
2219
2254
  if (node.childNodes.length === 1 && node.childNodes[0] instanceof TextNode) {
@@ -2275,7 +2310,7 @@ var SpanNodeHandler = class extends NodeHandler2 {
2275
2310
  };
2276
2311
 
2277
2312
  // src/importFromHtml/TableCellNodeHandler.ts
2278
- var import_node_html_parser22 = require("node-html-parser");
2313
+ var import_node_html_parser23 = require("node-html-parser");
2279
2314
 
2280
2315
  // src/utils/styleUtils.ts
2281
2316
  var extractStyleValue = (styleAttr, property, isNumeric = false, unit = "") => {
@@ -2324,7 +2359,7 @@ function createEmptyTableCellNode(isHeader = false) {
2324
2359
 
2325
2360
  // src/importFromHtml/TableCellNodeHandler.ts
2326
2361
  var isHtmlTableCellElement = (node) => {
2327
- return node instanceof import_node_html_parser22.HTMLElement && (node.tagName === "TD" || node.tagName === "TH");
2362
+ return node instanceof import_node_html_parser23.HTMLElement && (node.tagName === "TD" || node.tagName === "TH");
2328
2363
  };
2329
2364
  var TableCellNodeHandler2 = class extends NodeHandler2 {
2330
2365
  processNode(node) {
@@ -2366,10 +2401,10 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
2366
2401
  };
2367
2402
 
2368
2403
  // src/importFromHtml/TableNodeHandler.ts
2369
- var import_node_html_parser23 = require("node-html-parser");
2404
+ var import_node_html_parser24 = require("node-html-parser");
2370
2405
  var REFERENCE_TABLE_WIDTH = 720;
2371
2406
  var MINIMUM_REFERENCE_TABLE_WIDTH = 500;
2372
- var isHtmlTableElement = (node) => node instanceof import_node_html_parser23.HTMLElement && node.tagName === "TABLE";
2407
+ var isHtmlTableElement = (node) => node instanceof import_node_html_parser24.HTMLElement && node.tagName === "TABLE";
2373
2408
  var TableNodeHandler2 = class extends NodeHandler2 {
2374
2409
  processNode(node) {
2375
2410
  if (!isHtmlTableElement(node)) return null;
@@ -2524,9 +2559,9 @@ var TableNodeHandler2 = class extends NodeHandler2 {
2524
2559
  };
2525
2560
 
2526
2561
  // src/importFromHtml/TableRowNodeHandler.ts
2527
- var import_node_html_parser24 = require("node-html-parser");
2562
+ var import_node_html_parser25 = require("node-html-parser");
2528
2563
  var isHtmlTableRowElement = (node) => {
2529
- return node instanceof import_node_html_parser24.HTMLElement && node.tagName === "TR";
2564
+ return node instanceof import_node_html_parser25.HTMLElement && node.tagName === "TR";
2530
2565
  };
2531
2566
  var TableRowNodeHandler2 = class extends NodeHandler2 {
2532
2567
  processNode(node) {
@@ -2549,34 +2584,30 @@ var TableRowNodeHandler2 = class extends NodeHandler2 {
2549
2584
  };
2550
2585
 
2551
2586
  // src/importFromHtml/TextNodeHandler.ts
2552
- var import_node_html_parser25 = require("node-html-parser");
2553
- var TextNode2 = import_node_html_parser25.parse.TextNode;
2587
+ var import_node_html_parser26 = require("node-html-parser");
2588
+ var TextNode2 = import_node_html_parser26.parse.TextNode;
2554
2589
  var TextNodeHandler2 = class extends NodeHandler2 {
2555
2590
  processNode(node) {
2556
- if (node instanceof TextNode2 && !!node.parentNode.tagName) {
2557
- if (node.isWhitespace) {
2558
- return null;
2559
- }
2560
- const jsonNode = {
2561
- detail: 0,
2562
- format: 0,
2563
- mode: "normal",
2564
- style: "",
2565
- text: node.text,
2566
- type: "text",
2567
- version: 1
2568
- };
2569
- return jsonNode;
2570
- }
2571
- return null;
2591
+ if (!(node instanceof TextNode2)) return null;
2592
+ if (!node.parentNode.tagName) return null;
2593
+ const jsonNode = {
2594
+ detail: 0,
2595
+ format: 0,
2596
+ mode: "normal",
2597
+ style: "",
2598
+ text: node.text,
2599
+ type: "text",
2600
+ version: 1
2601
+ };
2602
+ return jsonNode;
2572
2603
  }
2573
2604
  };
2574
2605
 
2575
2606
  // src/importFromHtml/VariableNodeHandler.ts
2576
- var import_node_html_parser26 = require("node-html-parser");
2607
+ var import_node_html_parser27 = require("node-html-parser");
2577
2608
  var VariableNodeHandler2 = class extends NodeHandler2 {
2578
2609
  processNode(node) {
2579
- if (!(node instanceof import_node_html_parser26.HTMLElement) || !node.tagName) return null;
2610
+ if (!(node instanceof import_node_html_parser27.HTMLElement) || !node.tagName) return null;
2580
2611
  if (node.tagName !== "x-param".toUpperCase()) return null;
2581
2612
  return {
2582
2613
  variableName: node.getAttribute("data-x-name") || "undefined",
@@ -2589,7 +2620,7 @@ var VariableNodeHandler2 = class extends NodeHandler2 {
2589
2620
 
2590
2621
  // src/importFromHtml/traverse.ts
2591
2622
  var builder2 = new NodeHandlerChainBuilder();
2592
- var nodeHandlerChain2 = builder2.addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(ImageNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2623
+ var nodeHandlerChain2 = builder2.addHandler(CustomQuestionNodeHandler2).addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(ImageNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2593
2624
  function traverse2(node) {
2594
2625
  const result = nodeHandlerChain2.handle(node);
2595
2626
  if (result === null) return [];
@@ -2607,7 +2638,7 @@ function processChildren(node) {
2607
2638
  return result;
2608
2639
  }
2609
2640
  function processHtml(html) {
2610
- const root = (0, import_node_html_parser27.parse)(html);
2641
+ const root = (0, import_node_html_parser28.parse)(html);
2611
2642
  return processChildren(root);
2612
2643
  }
2613
2644
  function importFromHtml(html) {
package/dist/index.mjs CHANGED
@@ -317,9 +317,9 @@ var NodeHandlerChainBuilder = class {
317
317
  }
318
318
  };
319
319
 
320
- // src/typeGuards/isSerializedEssayQuestionNode.ts
321
- function isSerializedEssayQuestionNode(node) {
322
- return node?.type === "essay-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "maxWords" in node && typeof node.maxWords === "number" && "hideChat" in node && typeof node.hideChat === "boolean";
320
+ // src/typeGuards/isSerializedCustomQuestionNode.ts
321
+ function isSerializedCustomQuestionNode(node) {
322
+ return node?.type === "custom-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "name" in node && typeof node.name === "string" && "data" in node && typeof node.data === "string";
323
323
  }
324
324
 
325
325
  // src/exportToHtml/types.ts
@@ -342,6 +342,19 @@ var NodeHandler = class {
342
342
  }
343
343
  };
344
344
 
345
+ // src/exportToHtml/CustomQuestionNodeHandler.ts
346
+ var CustomQuestionNodeHandler = class extends NodeHandler {
347
+ processNode(node) {
348
+ if (!isSerializedCustomQuestionNode(node)) return null;
349
+ return `<x-custom id="${node.id}" data-x-prompt data-x-points="${node.points}" data-x-name="${node.name}"></x-custom>`;
350
+ }
351
+ };
352
+
353
+ // src/typeGuards/isSerializedEssayQuestionNode.ts
354
+ function isSerializedEssayQuestionNode(node) {
355
+ return node?.type === "essay-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "maxWords" in node && typeof node.maxWords === "number" && "hideChat" in node && typeof node.hideChat === "boolean";
356
+ }
357
+
345
358
  // src/exportToHtml/EssayQuestionNodeHandler.ts
346
359
  var EssayQuestionNodeHandler = class extends NodeHandler {
347
360
  processNode(node) {
@@ -1184,7 +1197,7 @@ var VariableNodeHandler = class extends NodeHandler {
1184
1197
 
1185
1198
  // src/exportToHtml/traverse.ts
1186
1199
  var builder = new NodeHandlerChainBuilder();
1187
- var nodeHandlerChain = builder.addHandler(EssayQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
1200
+ var nodeHandlerChain = builder.addHandler(CustomQuestionNodeHandler).addHandler(EssayQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
1188
1201
  var traverse = (node, metadata) => {
1189
1202
  return nodeHandlerChain.handle(node, metadata);
1190
1203
  };
@@ -1219,11 +1232,59 @@ function createEmptyParagraphNode(format = "") {
1219
1232
  };
1220
1233
  }
1221
1234
 
1235
+ // src/importFromHtml/CustomQuestionNodeHandler.ts
1236
+ import { HTMLElement } from "node-html-parser";
1237
+
1238
+ // src/importFromHtml/types.ts
1239
+ var NodeHandler2 = class {
1240
+ constructor() {
1241
+ this.nextHandler = null;
1242
+ }
1243
+ getChildNodesTextContent(childNodes) {
1244
+ return childNodes.reduce((acc, item) => {
1245
+ const text = item.textContent || "";
1246
+ return acc + text.trim() + " ";
1247
+ }, "").trimEnd();
1248
+ }
1249
+ setNext(handler) {
1250
+ this.nextHandler = handler;
1251
+ return handler;
1252
+ }
1253
+ handle(node) {
1254
+ const result = this.processNode(node);
1255
+ if (result) {
1256
+ return result;
1257
+ } else if (this.nextHandler) {
1258
+ return this.nextHandler.handle(node);
1259
+ }
1260
+ return null;
1261
+ }
1262
+ };
1263
+
1264
+ // src/importFromHtml/CustomQuestionNodeHandler.ts
1265
+ var TAG_X_CUSTOM = "x-custom";
1266
+ var CustomQuestionNodeHandler2 = class extends NodeHandler2 {
1267
+ processNode(node) {
1268
+ if (!(node instanceof HTMLElement) || node.tagName !== TAG_X_CUSTOM.toUpperCase()) {
1269
+ return null;
1270
+ }
1271
+ const jsonNode = {
1272
+ id: node.getAttribute("id") || "",
1273
+ points: Number(node.getAttribute("data-x-points") || 1),
1274
+ name: node.getAttribute("data-x-name") || "",
1275
+ data: "",
1276
+ type: "custom-question",
1277
+ version: 1
1278
+ };
1279
+ return jsonNode;
1280
+ }
1281
+ };
1282
+
1222
1283
  // src/importFromHtml/DivNodeHandler.ts
1223
- import { HTMLElement as HTMLElement2 } from "node-html-parser";
1284
+ import { HTMLElement as HTMLElement3 } from "node-html-parser";
1224
1285
 
1225
1286
  // src/importFromHtml/createNestedNodesFromHtml.ts
1226
- import { HTMLElement } from "node-html-parser";
1287
+ import { HTMLElement as HTMLElement2 } from "node-html-parser";
1227
1288
  var wrapInlinesInParagraph = (inlineNodes, format = "") => {
1228
1289
  const paragraph = createEmptyParagraphNode(format);
1229
1290
  paragraph.children = inlineNodes;
@@ -1249,9 +1310,9 @@ var extractFormatFromStyle = (styleAttribute) => {
1249
1310
  return "";
1250
1311
  };
1251
1312
  var createNestedNodesFromHtml = (node) => {
1252
- const parentStyleAttribute = node instanceof HTMLElement ? node.getAttribute("style") : null;
1313
+ const parentStyleAttribute = node instanceof HTMLElement2 ? node.getAttribute("style") : null;
1253
1314
  const format = extractFormatFromStyle(parentStyleAttribute);
1254
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement && node.childNodes[0].tagName === "BR") {
1315
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement2 && node.childNodes[0].tagName === "BR") {
1255
1316
  return [createEmptyParagraphNode(format)];
1256
1317
  }
1257
1318
  const results = [];
@@ -1387,36 +1448,10 @@ function processImageNodeContainer(node) {
1387
1448
  ];
1388
1449
  }
1389
1450
 
1390
- // src/importFromHtml/types.ts
1391
- var NodeHandler2 = class {
1392
- constructor() {
1393
- this.nextHandler = null;
1394
- }
1395
- getChildNodesTextContent(childNodes) {
1396
- return childNodes.reduce((acc, item) => {
1397
- const text = item.textContent || "";
1398
- return acc + text.trim() + " ";
1399
- }, "").trimEnd();
1400
- }
1401
- setNext(handler) {
1402
- this.nextHandler = handler;
1403
- return handler;
1404
- }
1405
- handle(node) {
1406
- const result = this.processNode(node);
1407
- if (result) {
1408
- return result;
1409
- } else if (this.nextHandler) {
1410
- return this.nextHandler.handle(node);
1411
- }
1412
- return null;
1413
- }
1414
- };
1415
-
1416
1451
  // src/importFromHtml/DivNodeHandler.ts
1417
1452
  var DivNodeHandler = class extends NodeHandler2 {
1418
1453
  isHtmlDivElement(node) {
1419
- return node instanceof HTMLElement2 && node.tagName === "DIV";
1454
+ return node instanceof HTMLElement3 && node.tagName === "DIV";
1420
1455
  }
1421
1456
  processNode(node) {
1422
1457
  if (!this.isHtmlDivElement(node)) {
@@ -1431,12 +1466,12 @@ var DivNodeHandler = class extends NodeHandler2 {
1431
1466
 
1432
1467
  // src/importFromHtml/EssayQuestionNodeHandler.ts
1433
1468
  import { nanoid } from "nanoid";
1434
- import { HTMLElement as HTMLElement3 } from "node-html-parser";
1469
+ import { HTMLElement as HTMLElement4 } from "node-html-parser";
1435
1470
  var TAG_X_ESSAY = "x-essay";
1436
1471
  var TAG_X_SYSTEM_MESSAGE = "x-ai-system-message";
1437
1472
  var EssayQuestionNodeHandler2 = class extends NodeHandler2 {
1438
1473
  processNode(node) {
1439
- if (!(node instanceof HTMLElement3) || node.tagName !== TAG_X_ESSAY.toUpperCase()) {
1474
+ if (!(node instanceof HTMLElement4) || node.tagName !== TAG_X_ESSAY.toUpperCase()) {
1440
1475
  return null;
1441
1476
  }
1442
1477
  const jsonNode = {
@@ -1462,7 +1497,7 @@ var EssayQuestionNodeHandler2 = class extends NodeHandler2 {
1462
1497
 
1463
1498
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1464
1499
  import { nanoid as nanoid2 } from "nanoid";
1465
- import { HTMLElement as HTMLElement4 } from "node-html-parser";
1500
+ import { HTMLElement as HTMLElement5 } from "node-html-parser";
1466
1501
 
1467
1502
  // src/importFromHtml/createNestedEditorFromHtml.ts
1468
1503
  function createNestedEditorFromHtml(node) {
@@ -1483,7 +1518,7 @@ function createNestedEditorFromHtml(node) {
1483
1518
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1484
1519
  var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1485
1520
  processNode(node) {
1486
- if (!(node instanceof HTMLElement4) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1521
+ if (!(node instanceof HTMLElement5) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1487
1522
  return null;
1488
1523
  const jsonNode = {
1489
1524
  id: node.getAttribute("id") ?? nanoid2(),
@@ -1500,7 +1535,7 @@ var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1500
1535
 
1501
1536
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1502
1537
  import { nanoid as nanoid3 } from "nanoid";
1503
- import { HTMLElement as HTMLElement5 } from "node-html-parser";
1538
+ import { HTMLElement as HTMLElement6 } from "node-html-parser";
1504
1539
 
1505
1540
  // src/importFromHtml/parseErrorToleranceAttribute.ts
1506
1541
  function parseErrorToleranceAttribute(attr) {
@@ -1512,7 +1547,7 @@ function parseErrorToleranceAttribute(attr) {
1512
1547
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1513
1548
  var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1514
1549
  processNode(node) {
1515
- if (!(node instanceof HTMLElement5) || node.tagName !== "x-space".toUpperCase())
1550
+ if (!(node instanceof HTMLElement6) || node.tagName !== "x-space".toUpperCase())
1516
1551
  return null;
1517
1552
  const spaceTypeAttr = node.getAttribute("data-x-type");
1518
1553
  const spaceType = spaceTypeAttr === "Text" || spaceTypeAttr === "Number" || spaceTypeAttr === "Dropdown" ? spaceTypeAttr : "Text";
@@ -1562,7 +1597,7 @@ var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1562
1597
 
1563
1598
  // src/importFromHtml/FinancialStatementQuestionNodeHandler.ts
1564
1599
  import { nanoid as nanoid4 } from "nanoid";
1565
- import { HTMLElement as HTMLElement6 } from "node-html-parser";
1600
+ import { HTMLElement as HTMLElement7 } from "node-html-parser";
1566
1601
  var TAG_X_FINANCIAL_STATEMENT = "x-financial-statement";
1567
1602
  var TAG_X_HEADER = "x-header";
1568
1603
  var TAG_X_ROWS = "x-rows";
@@ -1574,7 +1609,7 @@ var TAG_X_ENTRY = "x-entry";
1574
1609
  var TAG_X_AMOUNT = "x-amount";
1575
1610
  var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1576
1611
  processNode(node) {
1577
- if (!(node instanceof HTMLElement6) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1612
+ if (!(node instanceof HTMLElement7) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1578
1613
  return null;
1579
1614
  }
1580
1615
  const headerElement = node.querySelector(TAG_X_HEADER);
@@ -1589,7 +1624,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1589
1624
  version: 1
1590
1625
  };
1591
1626
  node.childNodes.forEach((child) => {
1592
- if (!(child instanceof HTMLElement6)) return;
1627
+ if (!(child instanceof HTMLElement7)) return;
1593
1628
  if (child.tagName === TAG_X_DISTRACTORS.toUpperCase()) {
1594
1629
  this.processDistractorsNode(child, jsonNode);
1595
1630
  } else if (child.tagName === TAG_X_ROWS.toUpperCase()) {
@@ -1600,7 +1635,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1600
1635
  }
1601
1636
  processDistractorsNode(distractorsNode, jsonNode) {
1602
1637
  for (const distractorsChild of distractorsNode.childNodes) {
1603
- if (!(distractorsChild instanceof HTMLElement6)) continue;
1638
+ if (!(distractorsChild instanceof HTMLElement7)) continue;
1604
1639
  if (distractorsChild.tagName !== TAG_X_DISTRACTOR.toUpperCase())
1605
1640
  continue;
1606
1641
  jsonNode.distractors.push({
@@ -1621,7 +1656,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1621
1656
  const contentDiv = headerElement.querySelector(
1622
1657
  'div > div:not([style*="display:flex"])'
1623
1658
  );
1624
- if (contentDiv && contentDiv instanceof HTMLElement6) {
1659
+ if (contentDiv && contentDiv instanceof HTMLElement7) {
1625
1660
  const contentDivClone = contentDiv.clone();
1626
1661
  contentDivClone.setAttribute("style", "text-align: left;");
1627
1662
  return createNestedEditorFromHtml(contentDivClone);
@@ -1641,7 +1676,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1641
1676
  }
1642
1677
  processRowsNode(rowsNode, jsonNode) {
1643
1678
  for (const rowsChild of rowsNode.childNodes) {
1644
- if (!(rowsChild instanceof HTMLElement6)) continue;
1679
+ if (!(rowsChild instanceof HTMLElement7)) continue;
1645
1680
  if (rowsChild.tagName === TAG_X_HEADING.toUpperCase()) {
1646
1681
  this.processHeadingRow(rowsChild, jsonNode);
1647
1682
  } else if (rowsChild.tagName === TAG_X_LINE.toUpperCase()) {
@@ -1675,7 +1710,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1675
1710
  };
1676
1711
 
1677
1712
  // src/importFromHtml/FormattedNodeHandler.ts
1678
- import { HTMLElement as HTMLElement7 } from "node-html-parser";
1713
+ import { HTMLElement as HTMLElement8 } from "node-html-parser";
1679
1714
  var IS_BOLD2 = 1;
1680
1715
  var IS_ITALIC2 = 1 << 1;
1681
1716
  var IS_STRIKETHROUGH2 = 1 << 2;
@@ -1715,7 +1750,7 @@ function formatToProps(format) {
1715
1750
  }
1716
1751
  var FormattedNodeHandler = class extends NodeHandler2 {
1717
1752
  processNode(node) {
1718
- if (!(node instanceof HTMLElement7)) return null;
1753
+ if (!(node instanceof HTMLElement8)) return null;
1719
1754
  const tagName = node.tagName;
1720
1755
  if (!tagName || !(tagName in TAG_TO_FORMAT)) return null;
1721
1756
  const formatFlag = TAG_TO_FORMAT[tagName];
@@ -1750,11 +1785,11 @@ var FormattedNodeHandler = class extends NodeHandler2 {
1750
1785
  };
1751
1786
 
1752
1787
  // src/importFromHtml/HorizontalRuleNodeHandler.ts
1753
- import { HTMLElement as HTMLElement8 } from "node-html-parser";
1788
+ import { HTMLElement as HTMLElement9 } from "node-html-parser";
1754
1789
  var TAG_HR = "hr";
1755
1790
  var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1756
1791
  processNode(node) {
1757
- if (!(node instanceof HTMLElement8) || node.tagName !== TAG_HR.toUpperCase()) {
1792
+ if (!(node instanceof HTMLElement9) || node.tagName !== TAG_HR.toUpperCase()) {
1758
1793
  return null;
1759
1794
  }
1760
1795
  const horizontalRuleNode = {
@@ -1766,11 +1801,11 @@ var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1766
1801
  };
1767
1802
 
1768
1803
  // src/importFromHtml/ImageNodeHandler.ts
1769
- import { HTMLElement as HTMLElement9 } from "node-html-parser";
1804
+ import { HTMLElement as HTMLElement10 } from "node-html-parser";
1770
1805
  var TAG_IMG = "img";
1771
1806
  var ImageNodeHandler2 = class extends NodeHandler2 {
1772
1807
  processNode(node) {
1773
- if (!(node instanceof HTMLElement9) || node.tagName !== TAG_IMG.toUpperCase()) {
1808
+ if (!(node instanceof HTMLElement10) || node.tagName !== TAG_IMG.toUpperCase()) {
1774
1809
  return null;
1775
1810
  }
1776
1811
  return createImageNode(
@@ -1786,11 +1821,11 @@ var ImageNodeHandler2 = class extends NodeHandler2 {
1786
1821
 
1787
1822
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1788
1823
  import { nanoid as nanoid6 } from "nanoid";
1789
- import { HTMLElement as HTMLElement11 } from "node-html-parser";
1824
+ import { HTMLElement as HTMLElement12 } from "node-html-parser";
1790
1825
 
1791
1826
  // src/importFromHtml/createOnePerLineDistractorNode.ts
1792
1827
  import { nanoid as nanoid5 } from "nanoid";
1793
- import { HTMLElement as HTMLElement10 } from "node-html-parser";
1828
+ import { HTMLElement as HTMLElement11 } from "node-html-parser";
1794
1829
  function extractDistractorId(id) {
1795
1830
  if (!id) return null;
1796
1831
  const parts = id.split("|");
@@ -1803,7 +1838,7 @@ var createOnePerLineDistractorNode = (node) => {
1803
1838
  distractorEditor.editorState.root.children = [];
1804
1839
  let distractorId = null;
1805
1840
  distractors.forEach((distractor) => {
1806
- if (!(distractor instanceof HTMLElement10)) return;
1841
+ if (!(distractor instanceof HTMLElement11)) return;
1807
1842
  distractorId = distractorId ?? extractDistractorId(distractor.getAttribute("id"));
1808
1843
  distractorEditor.editorState.root.children.push(
1809
1844
  ...createNestedNodesFromHtml(distractor)
@@ -1821,7 +1856,7 @@ var createOnePerLineDistractorNode = (node) => {
1821
1856
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1822
1857
  var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1823
1858
  processNode(node) {
1824
- if (!(node instanceof HTMLElement11) || node.tagName !== "x-journal-entry".toUpperCase())
1859
+ if (!(node instanceof HTMLElement12) || node.tagName !== "x-journal-entry".toUpperCase())
1825
1860
  return null;
1826
1861
  const jsonNode = {
1827
1862
  id: node.getAttribute("id") ?? nanoid6(),
@@ -1836,7 +1871,7 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1836
1871
  };
1837
1872
  const lineItems = node.querySelectorAll("x-line-item");
1838
1873
  lineItems.forEach((lineItem) => {
1839
- if (!(lineItem instanceof HTMLElement11)) return;
1874
+ if (!(lineItem instanceof HTMLElement12)) return;
1840
1875
  const accountElement = lineItem.querySelector("x-account");
1841
1876
  const debitElement = lineItem.querySelector("x-debit");
1842
1877
  const creditElement = lineItem.querySelector("x-credit");
@@ -1865,10 +1900,10 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1865
1900
  };
1866
1901
 
1867
1902
  // src/importFromHtml/LineBreakNodeHandler.ts
1868
- import { HTMLElement as HTMLElement12 } from "node-html-parser";
1903
+ import { HTMLElement as HTMLElement13 } from "node-html-parser";
1869
1904
  var LineBreakNodeHandler2 = class extends NodeHandler2 {
1870
1905
  processNode(node) {
1871
- if (!(node instanceof HTMLElement12)) return null;
1906
+ if (!(node instanceof HTMLElement13)) return null;
1872
1907
  if (node.tagName !== "BR") return null;
1873
1908
  return {
1874
1909
  type: "linebreak",
@@ -1878,11 +1913,11 @@ var LineBreakNodeHandler2 = class extends NodeHandler2 {
1878
1913
  };
1879
1914
 
1880
1915
  // src/importFromHtml/LinkNodeHandler.ts
1881
- import { HTMLElement as HTMLElement13 } from "node-html-parser";
1916
+ import { HTMLElement as HTMLElement14 } from "node-html-parser";
1882
1917
  var TAG_A = "a";
1883
1918
  var LinkNodeHandler2 = class extends NodeHandler2 {
1884
1919
  processNode(node) {
1885
- if (!(node instanceof HTMLElement13) || node.tagName !== TAG_A.toUpperCase()) {
1920
+ if (!(node instanceof HTMLElement14) || node.tagName !== TAG_A.toUpperCase()) {
1886
1921
  return null;
1887
1922
  }
1888
1923
  const url = node.getAttribute("href") || "";
@@ -1911,10 +1946,10 @@ var LinkNodeHandler2 = class extends NodeHandler2 {
1911
1946
  };
1912
1947
 
1913
1948
  // src/importFromHtml/ListItemNodeHandler.ts
1914
- import { HTMLElement as HTMLElement14 } from "node-html-parser";
1949
+ import { HTMLElement as HTMLElement15 } from "node-html-parser";
1915
1950
  var ListItemNodeHandler2 = class extends NodeHandler2 {
1916
1951
  processNode(node) {
1917
- if (!(node instanceof HTMLElement14)) return null;
1952
+ if (!(node instanceof HTMLElement15)) return null;
1918
1953
  if (node.tagName !== "LI") return null;
1919
1954
  const jsonNode = {
1920
1955
  type: "listitem",
@@ -1935,10 +1970,10 @@ var ListItemNodeHandler2 = class extends NodeHandler2 {
1935
1970
  };
1936
1971
 
1937
1972
  // src/importFromHtml/ListNodeHandler.ts
1938
- import { HTMLElement as HTMLElement15 } from "node-html-parser";
1973
+ import { HTMLElement as HTMLElement16 } from "node-html-parser";
1939
1974
  var ListNodeHandler2 = class extends NodeHandler2 {
1940
1975
  processNode(node) {
1941
- if (!(node instanceof HTMLElement15)) return null;
1976
+ if (!(node instanceof HTMLElement16)) return null;
1942
1977
  if (node.tagName !== "UL" && node.tagName !== "OL") return null;
1943
1978
  const tag = node.tagName.toLowerCase();
1944
1979
  const listType = tag === "ol" ? "number" : "bullet";
@@ -1956,7 +1991,7 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1956
1991
  };
1957
1992
  let itemIndex = 1;
1958
1993
  node.childNodes.forEach((child) => {
1959
- if (child instanceof HTMLElement15 && child.tagName === "LI") {
1994
+ if (child instanceof HTMLElement16 && child.tagName === "LI") {
1960
1995
  const listItemNode = {
1961
1996
  type: "listitem",
1962
1997
  version: 1,
@@ -1981,10 +2016,10 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1981
2016
 
1982
2017
  // src/importFromHtml/MatchingQuestionNodeHandler.ts
1983
2018
  import { nanoid as nanoid7 } from "nanoid";
1984
- import { HTMLElement as HTMLElement16 } from "node-html-parser";
2019
+ import { HTMLElement as HTMLElement17 } from "node-html-parser";
1985
2020
  var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1986
2021
  processNode(node) {
1987
- if (!(node instanceof HTMLElement16) || node.tagName !== "x-matching".toUpperCase())
2022
+ if (!(node instanceof HTMLElement17) || node.tagName !== "x-matching".toUpperCase())
1988
2023
  return null;
1989
2024
  const jsonNode = {
1990
2025
  id: node.getAttribute("id") ?? nanoid7(),
@@ -1997,7 +2032,7 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1997
2032
  };
1998
2033
  const matches = node.querySelectorAll("x-match");
1999
2034
  matches.forEach((match) => {
2000
- if (!(match instanceof HTMLElement16)) return;
2035
+ if (!(match instanceof HTMLElement17)) return;
2001
2036
  const premise = match.querySelector("x-premise");
2002
2037
  const option = match.querySelector("x-option");
2003
2038
  if (!premise || !option) return;
@@ -2020,10 +2055,10 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
2020
2055
 
2021
2056
  // src/importFromHtml/MultipleOptionQuestionNodeHandler.ts
2022
2057
  import { nanoid as nanoid8 } from "nanoid";
2023
- import { HTMLElement as HTMLElement17 } from "node-html-parser";
2058
+ import { HTMLElement as HTMLElement18 } from "node-html-parser";
2024
2059
  var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
2025
2060
  processNode(node) {
2026
- if (!(node instanceof HTMLElement17)) return null;
2061
+ if (!(node instanceof HTMLElement18)) return null;
2027
2062
  if (node.tagName === "x-multiple-choice".toUpperCase())
2028
2063
  return this.processMultipleChoiceNode(node);
2029
2064
  else if (node.tagName === "x-multiple-answers".toUpperCase())
@@ -2063,7 +2098,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
2063
2098
  processOptions(node, jsonNode) {
2064
2099
  const childNodes = node.childNodes;
2065
2100
  childNodes.forEach((child) => {
2066
- if (!(child instanceof HTMLElement17)) return;
2101
+ if (!(child instanceof HTMLElement18)) return;
2067
2102
  if (child.tagName !== "x-option".toUpperCase()) return;
2068
2103
  jsonNode.options.push({
2069
2104
  id: child.getAttribute("id") ?? nanoid8(),
@@ -2075,7 +2110,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
2075
2110
  };
2076
2111
 
2077
2112
  // src/importFromHtml/ParagraphNodeHandler.ts
2078
- import { HTMLElement as HTMLElement18 } from "node-html-parser";
2113
+ import { HTMLElement as HTMLElement19 } from "node-html-parser";
2079
2114
  var TEXT_ALIGN_TO_FORMAT = {
2080
2115
  center: "center",
2081
2116
  end: "end",
@@ -2098,25 +2133,25 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
2098
2133
  return "";
2099
2134
  }
2100
2135
  processImageNode(node) {
2101
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement18 && node.childNodes[0].tagName === "IMG") {
2136
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement19 && node.childNodes[0].tagName === "IMG") {
2102
2137
  return traverse2(node.childNodes[0]);
2103
2138
  }
2104
2139
  return null;
2105
2140
  }
2106
2141
  processSpanImageNode(node) {
2107
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement18 && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof HTMLElement18 && node.childNodes[0].childNodes[0].tagName === "IMG") {
2142
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement19 && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof HTMLElement19 && node.childNodes[0].childNodes[0].tagName === "IMG") {
2108
2143
  return traverse2(node.childNodes[0].childNodes[0]);
2109
2144
  }
2110
2145
  return null;
2111
2146
  }
2112
2147
  processNode(node) {
2113
- if (!(node instanceof HTMLElement18)) return null;
2148
+ if (!(node instanceof HTMLElement19)) return null;
2114
2149
  if (node.tagName !== "P") return null;
2115
2150
  const imageNode = this.processImageNode(node) ?? this.processSpanImageNode(node);
2116
2151
  if (imageNode) return imageNode;
2117
2152
  const jsonNode = createEmptyParagraphNode();
2118
2153
  jsonNode.format = this.extractTextAlignment(node);
2119
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement18 && node.childNodes[0].tagName === "BR")
2154
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement19 && node.childNodes[0].tagName === "BR")
2120
2155
  return jsonNode;
2121
2156
  node.childNodes.forEach((child) => {
2122
2157
  const processedChildren = traverse2(child);
@@ -2128,10 +2163,10 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
2128
2163
 
2129
2164
  // src/importFromHtml/ShortAnswerQuestionNodeHandler.ts
2130
2165
  import { nanoid as nanoid9 } from "nanoid";
2131
- import { HTMLElement as HTMLElement19 } from "node-html-parser";
2166
+ import { HTMLElement as HTMLElement20 } from "node-html-parser";
2132
2167
  var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
2133
2168
  processNode(node) {
2134
- if (!(node instanceof HTMLElement19) || node.tagName !== "x-short-answer".toUpperCase())
2169
+ if (!(node instanceof HTMLElement20) || node.tagName !== "x-short-answer".toUpperCase())
2135
2170
  return null;
2136
2171
  return {
2137
2172
  id: node.getAttribute("id") ?? nanoid9(),
@@ -2147,13 +2182,13 @@ var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
2147
2182
  };
2148
2183
 
2149
2184
  // src/importFromHtml/SimulationQuestionNodeHandler.ts
2150
- import { HTMLElement as HTMLElement20 } from "node-html-parser";
2185
+ import { HTMLElement as HTMLElement21 } from "node-html-parser";
2151
2186
  var TAG_X_SIMULATION = "x-simulation";
2152
2187
  var TAG_X_SYSTEM_MESSAGE2 = "x-ai-system-message";
2153
2188
  var TAG_X_STEP2_INSTRUCTIONS = "x-step2-instructions";
2154
2189
  var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
2155
2190
  processNode(node) {
2156
- if (!(node instanceof HTMLElement20) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2191
+ if (!(node instanceof HTMLElement21) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2157
2192
  return null;
2158
2193
  }
2159
2194
  const jsonNode = {
@@ -2180,11 +2215,11 @@ var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
2180
2215
  };
2181
2216
 
2182
2217
  // src/importFromHtml/SpanNodeHandler.ts
2183
- import { HTMLElement as HTMLElement21, parse } from "node-html-parser";
2218
+ import { HTMLElement as HTMLElement22, parse } from "node-html-parser";
2184
2219
  var TextNode = parse.TextNode;
2185
2220
  var SpanNodeHandler = class extends NodeHandler2 {
2186
2221
  processNode(node) {
2187
- if (!(node instanceof HTMLElement21) || node.tagName !== "SPAN")
2222
+ if (!(node instanceof HTMLElement22) || node.tagName !== "SPAN")
2188
2223
  return null;
2189
2224
  const styleAttr = node.getAttribute("style") || "";
2190
2225
  if (node.childNodes.length === 1 && node.childNodes[0] instanceof TextNode) {
@@ -2246,7 +2281,7 @@ var SpanNodeHandler = class extends NodeHandler2 {
2246
2281
  };
2247
2282
 
2248
2283
  // src/importFromHtml/TableCellNodeHandler.ts
2249
- import { HTMLElement as HTMLElement22 } from "node-html-parser";
2284
+ import { HTMLElement as HTMLElement23 } from "node-html-parser";
2250
2285
 
2251
2286
  // src/utils/styleUtils.ts
2252
2287
  var extractStyleValue = (styleAttr, property, isNumeric = false, unit = "") => {
@@ -2295,7 +2330,7 @@ function createEmptyTableCellNode(isHeader = false) {
2295
2330
 
2296
2331
  // src/importFromHtml/TableCellNodeHandler.ts
2297
2332
  var isHtmlTableCellElement = (node) => {
2298
- return node instanceof HTMLElement22 && (node.tagName === "TD" || node.tagName === "TH");
2333
+ return node instanceof HTMLElement23 && (node.tagName === "TD" || node.tagName === "TH");
2299
2334
  };
2300
2335
  var TableCellNodeHandler2 = class extends NodeHandler2 {
2301
2336
  processNode(node) {
@@ -2337,10 +2372,10 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
2337
2372
  };
2338
2373
 
2339
2374
  // src/importFromHtml/TableNodeHandler.ts
2340
- import { HTMLElement as HTMLElement23 } from "node-html-parser";
2375
+ import { HTMLElement as HTMLElement24 } from "node-html-parser";
2341
2376
  var REFERENCE_TABLE_WIDTH = 720;
2342
2377
  var MINIMUM_REFERENCE_TABLE_WIDTH = 500;
2343
- var isHtmlTableElement = (node) => node instanceof HTMLElement23 && node.tagName === "TABLE";
2378
+ var isHtmlTableElement = (node) => node instanceof HTMLElement24 && node.tagName === "TABLE";
2344
2379
  var TableNodeHandler2 = class extends NodeHandler2 {
2345
2380
  processNode(node) {
2346
2381
  if (!isHtmlTableElement(node)) return null;
@@ -2495,9 +2530,9 @@ var TableNodeHandler2 = class extends NodeHandler2 {
2495
2530
  };
2496
2531
 
2497
2532
  // src/importFromHtml/TableRowNodeHandler.ts
2498
- import { HTMLElement as HTMLElement24 } from "node-html-parser";
2533
+ import { HTMLElement as HTMLElement25 } from "node-html-parser";
2499
2534
  var isHtmlTableRowElement = (node) => {
2500
- return node instanceof HTMLElement24 && node.tagName === "TR";
2535
+ return node instanceof HTMLElement25 && node.tagName === "TR";
2501
2536
  };
2502
2537
  var TableRowNodeHandler2 = class extends NodeHandler2 {
2503
2538
  processNode(node) {
@@ -2524,30 +2559,26 @@ import { parse as parse2 } from "node-html-parser";
2524
2559
  var TextNode2 = parse2.TextNode;
2525
2560
  var TextNodeHandler2 = class extends NodeHandler2 {
2526
2561
  processNode(node) {
2527
- if (node instanceof TextNode2 && !!node.parentNode.tagName) {
2528
- if (node.isWhitespace) {
2529
- return null;
2530
- }
2531
- const jsonNode = {
2532
- detail: 0,
2533
- format: 0,
2534
- mode: "normal",
2535
- style: "",
2536
- text: node.text,
2537
- type: "text",
2538
- version: 1
2539
- };
2540
- return jsonNode;
2541
- }
2542
- return null;
2562
+ if (!(node instanceof TextNode2)) return null;
2563
+ if (!node.parentNode.tagName) return null;
2564
+ const jsonNode = {
2565
+ detail: 0,
2566
+ format: 0,
2567
+ mode: "normal",
2568
+ style: "",
2569
+ text: node.text,
2570
+ type: "text",
2571
+ version: 1
2572
+ };
2573
+ return jsonNode;
2543
2574
  }
2544
2575
  };
2545
2576
 
2546
2577
  // src/importFromHtml/VariableNodeHandler.ts
2547
- import { HTMLElement as HTMLElement25 } from "node-html-parser";
2578
+ import { HTMLElement as HTMLElement26 } from "node-html-parser";
2548
2579
  var VariableNodeHandler2 = class extends NodeHandler2 {
2549
2580
  processNode(node) {
2550
- if (!(node instanceof HTMLElement25) || !node.tagName) return null;
2581
+ if (!(node instanceof HTMLElement26) || !node.tagName) return null;
2551
2582
  if (node.tagName !== "x-param".toUpperCase()) return null;
2552
2583
  return {
2553
2584
  variableName: node.getAttribute("data-x-name") || "undefined",
@@ -2560,7 +2591,7 @@ var VariableNodeHandler2 = class extends NodeHandler2 {
2560
2591
 
2561
2592
  // src/importFromHtml/traverse.ts
2562
2593
  var builder2 = new NodeHandlerChainBuilder();
2563
- var nodeHandlerChain2 = builder2.addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(ImageNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2594
+ var nodeHandlerChain2 = builder2.addHandler(CustomQuestionNodeHandler2).addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(ImageNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2564
2595
  function traverse2(node) {
2565
2596
  const result = nodeHandlerChain2.handle(node);
2566
2597
  if (result === null) return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@examind/block-sdk",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "@comment version": [
5
5
  "Don't specify package version here. It will be injected by publish workflow."
6
6
  ],
@@ -21,7 +21,7 @@
21
21
  "peerDependencies": {
22
22
  "nanoid": ">=3.0.0",
23
23
  "node-html-parser": ">=6.0.0",
24
- "@examind/block-types": "^0.1.28"
24
+ "@examind/block-types": "^0.1.30"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@eslint/js": "^9.17.0",
@@ -36,7 +36,7 @@
36
36
  "tsup": "^8.3.5",
37
37
  "typescript": "^5.7.2",
38
38
  "typescript-eslint": "^8.18.2",
39
- "@examind/block-types": "0.1.28"
39
+ "@examind/block-types": "0.1.30"
40
40
  },
41
41
  "dependencies": {
42
42
  "lodash-es": "4.17.21"