Commit 6992b396 by Liu

fix:提问自动进入子工作流

parent e9c54c3a
......@@ -16,6 +16,7 @@
"date-fns": "^3.6.0",
"docx-preview": "^0.3.6",
"github-markdown-css": "^5.8.0",
"mermaid": "^11.13.0",
"pdfjs-dist": "^5.4.149",
"react": "^18.3.1",
"react-dom": "^18.3.1",
......@@ -646,6 +647,18 @@
"node": ">=6.9.0"
}
},
"node_modules/@braintree/sanitize-url": {
"version": "7.1.2",
"resolved": "https://registry.npmmirror.com/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz",
"integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==",
"license": "MIT"
},
"node_modules/@chevrotain/types": {
"version": "11.1.2",
"resolved": "https://registry.npmmirror.com/@chevrotain/types/-/types-11.1.2.tgz",
"integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==",
"license": "Apache-2.0"
},
"node_modules/@clack/core": {
"version": "0.3.5",
"resolved": "https://registry.npmmirror.com/@clack/core/-/core-0.3.5.tgz",
......@@ -675,7 +688,7 @@
},
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
"version": "1.3.0",
"dev": true,
"extraneous": true,
"inBundle": true,
"license": "MIT",
"engines": {
......@@ -2698,6 +2711,51 @@
"deprecated": "Use @eslint/object-schema instead",
"license": "BSD-3-Clause"
},
"node_modules/@iconify/types": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz",
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
"license": "MIT"
},
"node_modules/@iconify/utils": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/@iconify/utils/-/utils-3.1.3.tgz",
"integrity": "sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw==",
"license": "MIT",
"dependencies": {
"@antfu/install-pkg": "^1.1.0",
"@iconify/types": "^2.0.0",
"import-meta-resolve": "^4.2.0"
}
},
"node_modules/@iconify/utils/node_modules/@antfu/install-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
"integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
"license": "MIT",
"dependencies": {
"package-manager-detector": "^1.3.0",
"tinyexec": "^1.0.1"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@iconify/utils/node_modules/package-manager-detector": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
"integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
"license": "MIT"
},
"node_modules/@iconify/utils/node_modules/tinyexec": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-1.1.2.tgz",
"integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@internationalized/date": {
"version": "3.6.0",
"resolved": "https://registry.npmmirror.com/@internationalized/date/-/date-3.6.0.tgz",
......@@ -2877,6 +2935,15 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@mermaid-js/parser": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/@mermaid-js/parser/-/parser-1.1.1.tgz",
"integrity": "sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==",
"license": "MIT",
"dependencies": {
"@chevrotain/types": "~11.1.1"
}
},
"node_modules/@module-federation/error-codes": {
"version": "0.17.1",
"resolved": "https://registry.npmmirror.com/@module-federation/error-codes/-/error-codes-0.17.1.tgz",
......@@ -6501,6 +6568,259 @@
"@types/node": "*"
}
},
"node_modules/@types/d3": {
"version": "7.4.3",
"resolved": "https://registry.npmmirror.com/@types/d3/-/d3-7.4.3.tgz",
"integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
"license": "MIT",
"dependencies": {
"@types/d3-array": "*",
"@types/d3-axis": "*",
"@types/d3-brush": "*",
"@types/d3-chord": "*",
"@types/d3-color": "*",
"@types/d3-contour": "*",
"@types/d3-delaunay": "*",
"@types/d3-dispatch": "*",
"@types/d3-drag": "*",
"@types/d3-dsv": "*",
"@types/d3-ease": "*",
"@types/d3-fetch": "*",
"@types/d3-force": "*",
"@types/d3-format": "*",
"@types/d3-geo": "*",
"@types/d3-hierarchy": "*",
"@types/d3-interpolate": "*",
"@types/d3-path": "*",
"@types/d3-polygon": "*",
"@types/d3-quadtree": "*",
"@types/d3-random": "*",
"@types/d3-scale": "*",
"@types/d3-scale-chromatic": "*",
"@types/d3-selection": "*",
"@types/d3-shape": "*",
"@types/d3-time": "*",
"@types/d3-time-format": "*",
"@types/d3-timer": "*",
"@types/d3-transition": "*",
"@types/d3-zoom": "*"
}
},
"node_modules/@types/d3-array": {
"version": "3.2.2",
"resolved": "https://registry.npmmirror.com/@types/d3-array/-/d3-array-3.2.2.tgz",
"integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
"license": "MIT"
},
"node_modules/@types/d3-axis": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-axis/-/d3-axis-3.0.6.tgz",
"integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
"license": "MIT",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-brush": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-brush/-/d3-brush-3.0.6.tgz",
"integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
"license": "MIT",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-chord": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-chord/-/d3-chord-3.0.6.tgz",
"integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==",
"license": "MIT"
},
"node_modules/@types/d3-color": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/@types/d3-color/-/d3-color-3.1.3.tgz",
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
"license": "MIT"
},
"node_modules/@types/d3-contour": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-contour/-/d3-contour-3.0.6.tgz",
"integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
"license": "MIT",
"dependencies": {
"@types/d3-array": "*",
"@types/geojson": "*"
}
},
"node_modules/@types/d3-delaunay": {
"version": "6.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
"integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==",
"license": "MIT"
},
"node_modules/@types/d3-dispatch": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz",
"integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==",
"license": "MIT"
},
"node_modules/@types/d3-drag": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-drag/-/d3-drag-3.0.7.tgz",
"integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
"license": "MIT",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-dsv": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz",
"integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==",
"license": "MIT"
},
"node_modules/@types/d3-ease": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/d3-ease/-/d3-ease-3.0.2.tgz",
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
"license": "MIT"
},
"node_modules/@types/d3-fetch": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz",
"integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
"license": "MIT",
"dependencies": {
"@types/d3-dsv": "*"
}
},
"node_modules/@types/d3-force": {
"version": "3.0.10",
"resolved": "https://registry.npmmirror.com/@types/d3-force/-/d3-force-3.0.10.tgz",
"integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==",
"license": "MIT"
},
"node_modules/@types/d3-format": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-format/-/d3-format-3.0.4.tgz",
"integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==",
"license": "MIT"
},
"node_modules/@types/d3-geo": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz",
"integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/d3-hierarchy": {
"version": "3.1.7",
"resolved": "https://registry.npmmirror.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",
"integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==",
"license": "MIT"
},
"node_modules/@types/d3-interpolate": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
"license": "MIT",
"dependencies": {
"@types/d3-color": "*"
}
},
"node_modules/@types/d3-path": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/@types/d3-path/-/d3-path-3.1.1.tgz",
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
"license": "MIT"
},
"node_modules/@types/d3-polygon": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz",
"integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==",
"license": "MIT"
},
"node_modules/@types/d3-quadtree": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz",
"integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==",
"license": "MIT"
},
"node_modules/@types/d3-random": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/@types/d3-random/-/d3-random-3.0.3.tgz",
"integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==",
"license": "MIT"
},
"node_modules/@types/d3-scale": {
"version": "4.0.9",
"resolved": "https://registry.npmmirror.com/@types/d3-scale/-/d3-scale-4.0.9.tgz",
"integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
"license": "MIT",
"dependencies": {
"@types/d3-time": "*"
}
},
"node_modules/@types/d3-scale-chromatic": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
"integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==",
"license": "MIT"
},
"node_modules/@types/d3-selection": {
"version": "3.0.11",
"resolved": "https://registry.npmmirror.com/@types/d3-selection/-/d3-selection-3.0.11.tgz",
"integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
"license": "MIT"
},
"node_modules/@types/d3-shape": {
"version": "3.1.8",
"resolved": "https://registry.npmmirror.com/@types/d3-shape/-/d3-shape-3.1.8.tgz",
"integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==",
"license": "MIT",
"dependencies": {
"@types/d3-path": "*"
}
},
"node_modules/@types/d3-time": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-time/-/d3-time-3.0.4.tgz",
"integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
"license": "MIT"
},
"node_modules/@types/d3-time-format": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz",
"integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==",
"license": "MIT"
},
"node_modules/@types/d3-timer": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-3.0.2.tgz",
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
"license": "MIT"
},
"node_modules/@types/d3-transition": {
"version": "3.0.9",
"resolved": "https://registry.npmmirror.com/@types/d3-transition/-/d3-transition-3.0.9.tgz",
"integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
"license": "MIT",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-zoom": {
"version": "3.0.8",
"resolved": "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
"integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
"license": "MIT",
"dependencies": {
"@types/d3-interpolate": "*",
"@types/d3-selection": "*"
}
},
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmmirror.com/@types/debug/-/debug-4.1.12.tgz",
......@@ -6547,6 +6867,12 @@
"@types/estree": "*"
}
},
"node_modules/@types/geojson": {
"version": "7946.0.16",
"resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.16.tgz",
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
"license": "MIT"
},
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz",
......@@ -6647,6 +6973,13 @@
"tapable": "^2.2.0"
}
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT",
"optional": true
},
"node_modules/@types/unist": {
"version": "2.0.11",
"resolved": "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz",
......@@ -7249,6 +7582,16 @@
"win32"
]
},
"node_modules/@upsetjs/venn.js": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@upsetjs/venn.js/-/venn.js-2.0.0.tgz",
"integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==",
"license": "MIT",
"optionalDependencies": {
"d3-selection": "^3.0.0",
"d3-transition": "^3.0.1"
}
},
"node_modules/@vitest/eslint-plugin": {
"version": "1.3.4",
"resolved": "https://registry.npmmirror.com/@vitest/eslint-plugin/-/eslint-plugin-1.3.4.tgz",
......@@ -8550,184 +8893,713 @@
"dev": true,
"license": "MIT",
"dependencies": {
"browserslist": "^4.25.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
"browserslist": "^4.25.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"license": "MIT"
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dev": true,
"license": "MIT",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cose-base": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/cose-base/-/cose-base-1.0.3.tgz",
"integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==",
"license": "MIT",
"dependencies": {
"layout-base": "^1.0.0"
}
},
"node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"import-fresh": "^3.3.0",
"js-yaml": "^4.1.0",
"parse-json": "^5.2.0",
"path-type": "^4.0.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/d-fischer"
},
"peerDependencies": {
"typescript": ">=4.9.5"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
"license": "Apache-2.0",
"bin": {
"crc32": "bin/crc32.njs"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/css-select": {
"version": "5.2.2",
"resolved": "https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz",
"integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/css-what": {
"version": "6.2.2",
"resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz",
"integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/csso": {
"version": "5.0.5",
"resolved": "https://registry.npmmirror.com/csso/-/csso-5.0.5.tgz",
"integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"css-tree": "~2.2.0"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.2.1.tgz",
"integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"dev": true,
"license": "MIT",
"dependencies": {
"mdn-data": "2.0.28",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
"resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.28.tgz",
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/cytoscape": {
"version": "3.33.4",
"resolved": "https://registry.npmmirror.com/cytoscape/-/cytoscape-3.33.4.tgz",
"integrity": "sha512-HIN5Pmd9MrX9BkV7tDwnOcEJCSFvCpc8X97h3f508J6I5FsqAY65wKOCvgH2CuP42CaahWaz4tuh32SOOIH7ww==",
"license": "MIT",
"engines": {
"node": ">=0.10"
}
},
"node_modules/cytoscape-cose-bilkent": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz",
"integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==",
"license": "MIT",
"dependencies": {
"cose-base": "^1.0.0"
},
"peerDependencies": {
"cytoscape": "^3.2.0"
}
},
"node_modules/cytoscape-fcose": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",
"integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",
"license": "MIT",
"dependencies": {
"cose-base": "^2.2.0"
},
"peerDependencies": {
"cytoscape": "^3.2.0"
}
},
"node_modules/cytoscape-fcose/node_modules/cose-base": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/cose-base/-/cose-base-2.2.0.tgz",
"integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",
"license": "MIT",
"dependencies": {
"layout-base": "^2.0.0"
}
},
"node_modules/cytoscape-fcose/node_modules/layout-base": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/layout-base/-/layout-base-2.0.1.tgz",
"integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==",
"license": "MIT"
},
"node_modules/d3": {
"version": "7.9.0",
"resolved": "https://registry.npmmirror.com/d3/-/d3-7.9.0.tgz",
"integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",
"license": "ISC",
"dependencies": {
"d3-array": "3",
"d3-axis": "3",
"d3-brush": "3",
"d3-chord": "3",
"d3-color": "3",
"d3-contour": "4",
"d3-delaunay": "6",
"d3-dispatch": "3",
"d3-drag": "3",
"d3-dsv": "3",
"d3-ease": "3",
"d3-fetch": "3",
"d3-force": "3",
"d3-format": "3",
"d3-geo": "3",
"d3-hierarchy": "3",
"d3-interpolate": "3",
"d3-path": "3",
"d3-polygon": "3",
"d3-quadtree": "3",
"d3-random": "3",
"d3-scale": "4",
"d3-scale-chromatic": "3",
"d3-selection": "3",
"d3-shape": "3",
"d3-time": "3",
"d3-time-format": "4",
"d3-timer": "3",
"d3-transition": "3",
"d3-zoom": "3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-array": {
"version": "3.2.4",
"resolved": "https://registry.npmmirror.com/d3-array/-/d3-array-3.2.4.tgz",
"integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
"license": "ISC",
"dependencies": {
"internmap": "1 - 2"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-axis": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-axis/-/d3-axis-3.0.0.tgz",
"integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-brush": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-brush/-/d3-brush-3.0.0.tgz",
"integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
"license": "ISC",
"dependencies": {
"d3-dispatch": "1 - 3",
"d3-drag": "2 - 3",
"d3-interpolate": "1 - 3",
"d3-selection": "3",
"d3-transition": "3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-chord": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-chord/-/d3-chord-3.0.1.tgz",
"integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
"license": "ISC",
"dependencies": {
"d3-path": "1 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-color": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz",
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-contour": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/d3-contour/-/d3-contour-4.0.2.tgz",
"integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
"license": "ISC",
"dependencies": {
"d3-array": "^3.2.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-delaunay": {
"version": "6.0.4",
"resolved": "https://registry.npmmirror.com/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
"integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
"license": "ISC",
"dependencies": {
"delaunator": "5"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-dispatch": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-drag": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz",
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
"license": "ISC",
"dependencies": {
"d3-dispatch": "1 - 3",
"d3-selection": "3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-dsv": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-dsv/-/d3-dsv-3.0.1.tgz",
"integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
"license": "ISC",
"dependencies": {
"commander": "7",
"iconv-lite": "0.6",
"rw": "1"
},
"bin": {
"csv2json": "bin/dsv2json.js",
"csv2tsv": "bin/dsv2dsv.js",
"dsv2dsv": "bin/dsv2dsv.js",
"dsv2json": "bin/dsv2json.js",
"json2csv": "bin/json2dsv.js",
"json2dsv": "bin/json2dsv.js",
"json2tsv": "bin/json2dsv.js",
"tsv2csv": "bin/dsv2dsv.js",
"tsv2json": "bin/dsv2json.js"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-dsv/node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"license": "MIT",
"engines": {
"node": ">= 10"
}
},
"node_modules/d3-dsv/node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/d3-ease": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz",
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-fetch": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-fetch/-/d3-fetch-3.0.1.tgz",
"integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
"license": "ISC",
"dependencies": {
"d3-dsv": "1 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-force": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-force/-/d3-force-3.0.0.tgz",
"integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
"license": "ISC",
"dependencies": {
"d3-dispatch": "1 - 3",
"d3-quadtree": "1 - 3",
"d3-timer": "1 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-format": {
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/d3-format/-/d3-format-3.1.2.tgz",
"integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-geo": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/d3-geo/-/d3-geo-3.1.1.tgz",
"integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
"license": "ISC",
"dependencies": {
"d3-array": "2.5.0 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-hierarchy": {
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
"integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-interpolate": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
"license": "ISC",
"dependencies": {
"d3-color": "1 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-path": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/d3-path/-/d3-path-3.1.0.tgz",
"integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-polygon": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-polygon/-/d3-polygon-3.0.1.tgz",
"integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-quadtree": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
"integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-random": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-random/-/d3-random-3.0.1.tgz",
"integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-sankey": {
"version": "0.12.3",
"resolved": "https://registry.npmmirror.com/d3-sankey/-/d3-sankey-0.12.3.tgz",
"integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-array": "1 - 2",
"d3-shape": "^1.2.0"
}
},
"node_modules/d3-sankey/node_modules/d3-array": {
"version": "2.12.1",
"resolved": "https://registry.npmmirror.com/d3-array/-/d3-array-2.12.1.tgz",
"integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
"license": "BSD-3-Clause",
"dependencies": {
"internmap": "^1.0.0"
}
},
"node_modules/d3-sankey/node_modules/d3-path": {
"version": "1.0.9",
"resolved": "https://registry.npmmirror.com/d3-path/-/d3-path-1.0.9.tgz",
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==",
"license": "BSD-3-Clause"
},
"node_modules/d3-sankey/node_modules/d3-shape": {
"version": "1.3.7",
"resolved": "https://registry.npmmirror.com/d3-shape/-/d3-shape-1.3.7.tgz",
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-path": "1"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"license": "MIT"
"node_modules/d3-sankey/node_modules/internmap": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/internmap/-/internmap-1.0.1.tgz",
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
"license": "ISC"
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dev": true,
"license": "MIT",
"node_modules/d3-scale": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/d3-scale/-/d3-scale-4.0.2.tgz",
"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
"license": "ISC",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
"d3-array": "2.10.0 - 3",
"d3-format": "1 - 3",
"d3-interpolate": "1.2.0 - 3",
"d3-time": "2.1.1 - 3",
"d3-time-format": "2 - 4"
},
"engines": {
"node": ">= 0.10"
"node": ">=12"
}
},
"node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
"dev": true,
"license": "MIT",
"node_modules/d3-scale-chromatic": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
"integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
"license": "ISC",
"dependencies": {
"import-fresh": "^3.3.0",
"js-yaml": "^4.1.0",
"parse-json": "^5.2.0",
"path-type": "^4.0.0"
"d3-color": "1 - 3",
"d3-interpolate": "1 - 3"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/d-fischer"
},
"peerDependencies": {
"typescript": ">=4.9.5"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"node": ">=12"
}
},
"node_modules/crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
"license": "Apache-2.0",
"bin": {
"crc32": "bin/crc32.njs"
},
"node_modules/d3-selection": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"license": "ISC",
"engines": {
"node": ">=0.8"
"node": ">=12"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"node_modules/d3-shape": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/d3-shape/-/d3-shape-3.2.0.tgz",
"integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
"license": "ISC",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
"d3-path": "^3.1.0"
},
"engines": {
"node": ">= 8"
"node": ">=12"
}
},
"node_modules/css-select": {
"version": "5.2.2",
"resolved": "https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz",
"integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
"dev": true,
"license": "BSD-2-Clause",
"node_modules/d3-time": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/d3-time/-/d3-time-3.1.0.tgz",
"integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
"license": "ISC",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
"d3-array": "2 - 3"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
"engines": {
"node": ">=12"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"dev": true,
"license": "MIT",
"node_modules/d3-time-format": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/d3-time-format/-/d3-time-format-4.1.0.tgz",
"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
"license": "ISC",
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
"d3-time": "1 - 3"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
"node": ">=12"
}
},
"node_modules/css-what": {
"version": "6.2.2",
"resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz",
"integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
"dev": true,
"license": "BSD-2-Clause",
"node_modules/d3-timer": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz",
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
"license": "ISC",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
"node": ">=12"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
"node_modules/d3-transition": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz",
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
"license": "ISC",
"dependencies": {
"d3-color": "1 - 3",
"d3-dispatch": "1 - 3",
"d3-ease": "1 - 3",
"d3-interpolate": "1 - 3",
"d3-timer": "1 - 3"
},
"engines": {
"node": ">=4"
"node": ">=12"
},
"peerDependencies": {
"d3-selection": "2 - 3"
}
},
"node_modules/csso": {
"version": "5.0.5",
"resolved": "https://registry.npmmirror.com/csso/-/csso-5.0.5.tgz",
"integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"dev": true,
"license": "MIT",
"node_modules/d3-zoom": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz",
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
"license": "ISC",
"dependencies": {
"css-tree": "~2.2.0"
"d3-dispatch": "1 - 3",
"d3-drag": "2 - 3",
"d3-interpolate": "1 - 3",
"d3-selection": "2 - 3",
"d3-transition": "2 - 3"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
"node": ">=12"
}
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.2.1.tgz",
"integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"dev": true,
"node_modules/dagre-d3-es": {
"version": "7.0.14",
"resolved": "https://registry.npmmirror.com/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz",
"integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==",
"license": "MIT",
"dependencies": {
"mdn-data": "2.0.28",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
"d3": "^7.9.0",
"lodash-es": "^4.17.21"
}
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
"resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.28.tgz",
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/date-fns": {
"version": "3.6.0",
"resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-3.6.0.tgz",
......@@ -8848,6 +9720,15 @@
"license": "MIT",
"peer": true
},
"node_modules/delaunator": {
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/delaunator/-/delaunator-5.1.0.tgz",
"integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==",
"license": "ISC",
"dependencies": {
"robust-predicates": "^3.0.2"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
......@@ -8977,6 +9858,15 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/dompurify": {
"version": "3.4.5",
"resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-3.4.5.tgz",
"integrity": "sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
},
"node_modules/domutils": {
"version": "3.2.2",
"resolved": "https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz",
......@@ -9246,6 +10136,16 @@
"node": ">= 0.4"
}
},
"node_modules/es-toolkit": {
"version": "1.46.1",
"resolved": "https://registry.npmmirror.com/es-toolkit/-/es-toolkit-1.46.1.tgz",
"integrity": "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==",
"license": "MIT",
"workspaces": [
"docs",
"benchmarks"
]
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
......@@ -11013,6 +11913,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/hachure-fill": {
"version": "0.5.2",
"resolved": "https://registry.npmmirror.com/hachure-fill/-/hachure-fill-0.5.2.tgz",
"integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==",
"license": "MIT"
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
......@@ -11380,6 +12286,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/import-meta-resolve": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
"integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
......@@ -11432,6 +12348,15 @@
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
}
},
"node_modules/internmap": {
"version": "2.0.3",
"resolved": "https://registry.npmmirror.com/internmap/-/internmap-2.0.3.tgz",
"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/intersection-observer": {
"version": "0.12.2",
"resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz",
......@@ -11913,6 +12838,31 @@
"setimmediate": "^1.0.5"
}
},
"node_modules/katex": {
"version": "0.16.47",
"resolved": "https://registry.npmmirror.com/katex/-/katex-0.16.47.tgz",
"integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==",
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
],
"license": "MIT",
"dependencies": {
"commander": "^8.3.0"
},
"bin": {
"katex": "cli.js"
}
},
"node_modules/katex/node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
......@@ -11922,6 +12872,17 @@
"json-buffer": "3.0.1"
}
},
"node_modules/khroma": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/khroma/-/khroma-2.1.0.tgz",
"integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="
},
"node_modules/layout-base": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/layout-base/-/layout-base-1.0.2.tgz",
"integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==",
"license": "MIT"
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz",
......@@ -12088,6 +13049,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.18.1",
"resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.18.1.tgz",
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
"license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
......@@ -12269,6 +13236,18 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/marked": {
"version": "16.4.2",
"resolved": "https://registry.npmmirror.com/marked/-/marked-16.4.2.tgz",
"integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==",
"license": "MIT",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
......@@ -13555,6 +14534,41 @@
"node": ">= 8"
}
},
"node_modules/mermaid": {
"version": "11.15.0",
"resolved": "https://registry.npmmirror.com/mermaid/-/mermaid-11.15.0.tgz",
"integrity": "sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==",
"license": "MIT",
"dependencies": {
"@braintree/sanitize-url": "^7.1.1",
"@iconify/utils": "^3.0.2",
"@mermaid-js/parser": "^1.1.1",
"@types/d3": "^7.4.3",
"@upsetjs/venn.js": "^2.0.0",
"cytoscape": "^3.33.1",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.2.0",
"d3": "^7.9.0",
"d3-sankey": "^0.12.3",
"dagre-d3-es": "7.0.14",
"dayjs": "^1.11.19",
"dompurify": "^3.3.1",
"es-toolkit": "^1.45.1",
"katex": "^0.16.25",
"khroma": "^2.1.0",
"marked": "^16.3.0",
"roughjs": "^4.6.6",
"stylis": "^4.3.6",
"ts-dedent": "^2.2.0",
"uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0"
}
},
"node_modules/mermaid/node_modules/dayjs": {
"version": "1.11.20",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz",
"integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==",
"license": "MIT"
},
"node_modules/micromark": {
"version": "2.11.4",
"resolved": "https://registry.npmmirror.com/micromark/-/micromark-2.11.4.tgz",
......@@ -14742,6 +15756,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/path-data-parser": {
"version": "0.1.0",
"resolved": "https://registry.npmmirror.com/path-data-parser/-/path-data-parser-0.1.0.tgz",
"integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==",
"license": "MIT"
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
......@@ -14905,6 +15925,22 @@
"node": ">=4"
}
},
"node_modules/points-on-curve": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/points-on-curve/-/points-on-curve-0.2.0.tgz",
"integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==",
"license": "MIT"
},
"node_modules/points-on-path": {
"version": "0.2.1",
"resolved": "https://registry.npmmirror.com/points-on-path/-/points-on-path-0.2.1.tgz",
"integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==",
"license": "MIT",
"dependencies": {
"path-data-parser": "0.1.0",
"points-on-curve": "0.2.0"
}
},
"node_modules/popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmmirror.com/popper.js/-/popper.js-1.16.1.tgz",
......@@ -16148,6 +17184,24 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/robust-predicates": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/robust-predicates/-/robust-predicates-3.0.3.tgz",
"integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==",
"license": "Unlicense"
},
"node_modules/roughjs": {
"version": "4.6.6",
"resolved": "https://registry.npmmirror.com/roughjs/-/roughjs-4.6.6.tgz",
"integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==",
"license": "MIT",
"dependencies": {
"hachure-fill": "^0.5.2",
"path-data-parser": "^0.1.0",
"points-on-curve": "^0.2.0",
"points-on-path": "^0.2.1"
}
},
"node_modules/rslog": {
"version": "1.2.11",
"resolved": "https://registry.npmmirror.com/rslog/-/rslog-1.2.11.tgz",
......@@ -16178,6 +17232,12 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/rw": {
"version": "1.3.3",
"resolved": "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz",
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
"license": "BSD-3-Clause"
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
......@@ -16203,7 +17263,6 @@
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"license": "MIT"
},
"node_modules/scheduler": {
......@@ -17069,6 +18128,12 @@
"inline-style-parser": "0.2.4"
}
},
"node_modules/stylis": {
"version": "4.4.0",
"resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.4.0.tgz",
"integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==",
"license": "MIT"
},
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz",
......@@ -17577,6 +18642,15 @@
"typescript": ">=4.0.0"
}
},
"node_modules/ts-dedent": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/ts-dedent/-/ts-dedent-2.2.0.tgz",
"integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
"license": "MIT",
"engines": {
"node": ">=6.10"
}
},
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
......@@ -17980,6 +19054,19 @@
"node": ">= 0.4.0"
}
},
"node_modules/uuid": {
"version": "14.0.0",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-14.0.0.tgz",
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
......
......@@ -4,7 +4,7 @@ import { Button } from '@heroui/react'
import { motion } from 'framer-motion'
import { useScroll } from 'ahooks'
import styles from './Chat.module.less'
import { type WorkflowParseOptions, getLastQaRecordWorkflowContext, hasQaWorkflowContext, hasWorkflowFormCards, isHiddenWorkflowRedirectControl, isHiddenWorkflowRedirectPayload, isWorkflowControlEnd, isWorkflowPacketEnd, markWorkflowFormSubmittedOnRecord, processApiResponse, resolveDisplayAnswerText, resolveWorkFlowSessionId, tryParseWorkflowControlJson } from './helper'
import { type WorkflowControlPayload, type WorkflowParseOptions, enrichWorkflowControlWithPacketQuestion, getLastQaRecordWorkflowContext, hasQaWorkflowContext, hasWorkflowFormCards, isHiddenWorkflowRedirectControl, isHiddenWorkflowRedirectPayload, isWorkflowControlEnd, isWorkflowControlPayloadComplete, isWorkflowEnterSubPayload, isWorkflowPacketEnd, markWorkflowFormSubmittedOnRecord, normalizeStreamAnswerChunk, parseWorkflowControlForStream, processApiResponse, resolveDisplayAnswerText, resolveWorkFlowSessionId } from './helper'
import type { WorkflowParamMap } from './lib/workflowCardForm'
import { ChatWelcome } from './components/ChatWelcome'
import { ChatItemUser } from './components/ChatItem/ChatItemUser'
......@@ -28,10 +28,20 @@ type WorkflowStreamAnswer = Answer & {
workflowParseText?: string
workflowAnswerChunk?: string
workflowPacketEnd?: boolean
/** 任一分片解析到的工作流控制 JSON,流结束后用于自动续问 */
workflowDetectedControl?: WorkflowControlPayload
}
const PENDING_WORKFLOW_SILENT_BOOTSTRAP_KEY = 'pendingWorkflowSilentBootstrap'
function findLastAiIndex(items: ChatRecord[]): number {
for (let i = items.length - 1; i >= 0; i--) {
if (items[i].role === 'ai')
return i
}
return -1
}
function makeLocalGroupId(prefix: string) {
try {
// modern browsers
......@@ -126,6 +136,8 @@ export const Chat: React.FC = () => {
...(snapshot.workflowPacketEnd ? { packetEnd: true } : {}),
}
}, [])
/** 当前流式请求对应的 AI 气泡 groupId,避免写入错误的历史 AI 记录 */
const activeStreamingAiGroupIdRef = useRef<string | null>(null)
/** 工作流静默续跑(空问题开子/子流/表单提交):提交前已追加独立 AI 占位,流式勿再覆盖上一条 */
const workflowSilentAppendAiRef = useRef(false)
/** 本次 paramMap 表单提交对应的 AI 记录标识(recordId 或 groupId),流结束后标记 workflowFormSubmitted */
......@@ -285,19 +297,21 @@ export const Chat: React.FC = () => {
lastAnswer: WorkflowStreamAnswer,
) => {
const streamSnapshot = lastStreamedAiAnswerRef.current
const parseText = streamSnapshot?.workflowParseText
?? lastAnswer.workflowParseText
?? lastAnswer.answer
?? ''
const parseOptions = buildWorkflowParseOptions(streamSnapshot ?? lastAnswer)
const parsedAnswer = tryParseWorkflowControlJson(parseText, parseOptions)
const packetQuestion = (lastAnswer as WorkflowStreamAnswer & { question?: string }).question
const wfParseText = trimSpacesOnly(
lastAnswer.workflowParseText ?? streamSnapshot?.workflowParseText ?? lastAnswer.answer ?? '',
)
let parsedAnswer = parseWorkflowControlForStream(wfParseText, parseOptions, packetQuestion)
if (!parsedAnswer) {
const detected = lastAnswer.workflowDetectedControl ?? streamSnapshot?.workflowDetectedControl
const enriched = enrichWorkflowControlWithPacketQuestion(detected, packetQuestion, wfParseText)
if (enriched && isWorkflowControlPayloadComplete(enriched))
parsedAnswer = enriched
}
const lastAnswerSessionId = resolveWorkFlowSessionId(lastAnswer)
const hasHiddenRedirect = isHiddenWorkflowRedirectPayload(parsedAnswer)
const hasEnterSubSignal = Boolean(
parsedAnswer?.recordType != null
&& String(parsedAnswer.recordType).trim()
&& parsedAnswer.question != null,
)
const hasEnterSubSignal = isWorkflowEnterSubPayload(parsedAnswer)
const wf = businessInsightWorkflowRef.current
const shouldHandleWorkflowAnswer = Boolean(lastAnswerSessionId)
......@@ -395,7 +409,7 @@ export const Chat: React.FC = () => {
return
}
if (parsedAnswer?.recordType != null && parsedAnswer.question != null) {
if (hasEnterSubSignal && parsedAnswer) {
const subRecordType = String(parsedAnswer.recordType).trim()
const controlQ = parsedAnswer.question != null ? String(parsedAnswer.question).trim() : ''
const mainUserQ = lastMainUserQuestionRef.current?.trim() || ''
......@@ -416,6 +430,7 @@ export const Chat: React.FC = () => {
pendingSubQuestionRef.current = pendingQ || null
pendingSubOpenRecordTypeRef.current = subRecordType
expectingSubWorkflowOpenRef.current = true
console.log('[Chat WF] 自动开子工作流', { recordType: subRecordType, pendingQ, mainSessionId })
queueMicrotask(() => {
void handleSubmitQuestionRef.current?.('', undefined, resolveWorkflowToolId() || undefined, {
recordType: subRecordType,
......@@ -476,9 +491,68 @@ export const Chat: React.FC = () => {
/** 处理正常stream的数据 */
const handleStreamMesageData = (msg: any, question: string) => {
const packetData = msg.content?.data || {}
const answerChunk = normalizeStreamAnswerChunk(packetData.answer)
const prevRef = lastStreamedAiAnswerRef.current
const previousRaw = prevRef?.workflowParseText ?? ''
const originalAnswer = previousRaw + answerChunk
let filteredAnswer = originalAnswer.replace(/\([^)]*\)/g, (match, offset, str) => {
return str[offset - 1] === ']' ? match : ''
})
filteredAnswer = filteredAnswer.replace(/\[参考文档(?:[^]*》\s*)+\]/g, '')
filteredAnswer = trimSpacesOnly(filteredAnswer)
const packetEnd = isWorkflowPacketEnd(packetData)
const streamParseOptions: WorkflowParseOptions | undefined = (
answerChunk || packetEnd
)
? {
...(answerChunk ? { answerChunk } : {}),
...(packetEnd ? { packetEnd: true } : {}),
}
: undefined
const { endAnswerFlag: _syncOmitEnd, ...dataWithoutEndFlag } = packetData
const wfParseText = trimSpacesOnly(originalAnswer)
const packetControl = parseWorkflowControlForStream(
wfParseText,
streamParseOptions,
dataWithoutEndFlag.question,
)
filteredAnswer = resolveDisplayAnswerText(filteredAnswer, streamParseOptions, dataWithoutEndFlag.question)
const syncSessionId = resolveWorkFlowSessionId(
{ ...prevRef, ...dataWithoutEndFlag },
prevRef?.workFlowSessionId,
)
// 同步写入 ref:流 fetch resolve 时 React 可能尚未执行 setAllItems,避免读不到控制 JSON
if (answerChunk || packetEnd || packetControl) {
lastStreamedAiAnswerRef.current = {
...(prevRef || {}),
...dataWithoutEndFlag,
workFlowSessionId: syncSessionId,
recordId: dataWithoutEndFlag.recordId ?? prevRef?.recordId,
cardList: Array.isArray(dataWithoutEndFlag.cardList) && dataWithoutEndFlag.cardList.length > 0
? dataWithoutEndFlag.cardList
: prevRef?.cardList,
answer: filteredAnswer,
workflowParseText: wfParseText,
workflowAnswerChunk: answerChunk,
workflowPacketEnd: packetEnd || prevRef?.workflowPacketEnd,
...(packetControl ? { workflowDetectedControl: packetControl } : {}),
}
if (packetControl) {
console.log('[Chat WF] 分片识别到控制 JSON', {
recordType: packetControl.recordType,
question: packetControl.question,
packetQuestion: dataWithoutEndFlag.question,
parseTextTail: trimSpacesOnly(originalAnswer).slice(-120),
complete: isWorkflowControlPayloadComplete(packetControl),
displayAnswer: filteredAnswer,
packetEnd,
})
}
}
setAllItems((prevItems) => {
const newItems = [...prevItems] // 创建数组的浅拷贝
const lastIndex = newItems.length - 1
const isEmptyQuestion = !question.trim()
// 提质增效自动欢迎语场景:空问题的流式回答应追加在历史记录之后,避免复用最后一条历史 AI 记录
const shouldAlwaysAppendAi = isAutoSubmitQualityImprovementRef.current && isEmptyQuestion
......@@ -519,75 +593,62 @@ export const Chat: React.FC = () => {
}
}
let lastAiIndex = findLastAiIndex(newItems)
const streamingGroupId = activeStreamingAiGroupIdRef.current
if (streamingGroupId) {
let streamingIndex = newItems.findIndex(
item => item.role === 'ai' && item.groupId === streamingGroupId,
)
if (streamingIndex < 0) {
newItems.push({
role: 'ai',
groupId: streamingGroupId,
answerList: [{ answer: '', isShow: false }],
} as ChatRecord)
streamingIndex = newItems.length - 1
}
lastAiIndex = streamingIndex
}
// 如果是空问题且需要追加新的 AI 记录(历史末尾没有 AI,或提质增效自动欢迎语场景),则添加 AI 回答占位
if (isEmptyQuestion && (lastIndex < 0 || newItems[lastIndex].role !== 'ai' || shouldAlwaysAppendAi)) {
if (isEmptyQuestion && (lastAiIndex < 0 || shouldAlwaysAppendAi)) {
newItems.push({
role: 'ai',
groupId: makeLocalGroupId('ai'),
answerList: [{ answer: '' }],
} as ChatRecord)
lastAiIndex = newItems.length - 1
}
const currentIndex = newItems.length - 1
if (currentIndex >= 0 && newItems[currentIndex].role === 'ai') {
if (lastAiIndex >= 0) {
// 创建最后一项的新对象,合并现有数据和新的 answer
const existingAnswer = newItems[currentIndex].answerList?.[0] || {}
const originalAnswer = (existingAnswer.answer || '') + (msg.content.data.answer ?? '\n')
// 移除所有括号及其内容(但保留 Markdown 链接语法中的 ](...))
let filteredAnswer = originalAnswer.replace(/\([^)]*\)/g, (match, offset, str) => {
return str[offset - 1] === ']' ? match : ''
})
// 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容
filteredAnswer = filteredAnswer.replace(/\[参考文档(?:[^]*》\s*)+\]/g, '')
// 只移除空格和制表符,保留换行符(避免移除末尾的 \n\n)
filteredAnswer = trimSpacesOnly(filteredAnswer)
const packetData = msg.content.data || {}
const answerChunk = typeof packetData.answer === 'string' ? packetData.answer : ''
const packetEnd = isWorkflowPacketEnd(packetData)
const streamParseOptions: WorkflowParseOptions | undefined = (
answerChunk || packetEnd
)
? {
...(answerChunk ? { answerChunk } : {}),
...(packetEnd ? { packetEnd: true } : {}),
}
: undefined
filteredAnswer = resolveDisplayAnswerText(filteredAnswer, streamParseOptions)
// 在流式响应过程中,忽略服务器返回的 endAnswerFlag,避免过早禁用输入框
const { endAnswerFlag: _omitEndAnswerFlag, ...dataWithoutEndFlag } = packetData
const existingAnswer = newItems[lastAiIndex].answerList?.[0] || {}
const mergedFromRef = lastStreamedAiAnswerRef.current
const chunkToolId = dataWithoutEndFlag.toolId != null ? String(dataWithoutEndFlag.toolId).trim() : ''
const chunkRecordType = dataWithoutEndFlag.recordType != null ? String(dataWithoutEndFlag.recordType).trim() : ''
if (chunkToolId && chunkRecordType)
setWorkflowLastToolPair(chunkToolId, chunkRecordType)
const resolvedSessionId = resolveWorkFlowSessionId(
{ ...existingAnswer, ...dataWithoutEndFlag },
existingAnswer.workFlowSessionId,
)
// 保留之前保存的 workFlowSessionId 和 recordId,避免被覆盖
const mergedAnswer: Answer = {
const mergedAnswer: WorkflowStreamAnswer = {
...existingAnswer,
...dataWithoutEndFlag,
workFlowSessionId: resolvedSessionId,
recordId: dataWithoutEndFlag.recordId ?? existingAnswer.recordId,
cardList: Array.isArray(dataWithoutEndFlag.cardList) && dataWithoutEndFlag.cardList.length > 0
? dataWithoutEndFlag.cardList
: existingAnswer.cardList,
...(mergedFromRef || dataWithoutEndFlag),
workFlowSessionId: mergedFromRef?.workFlowSessionId
?? resolveWorkFlowSessionId({ ...existingAnswer, ...dataWithoutEndFlag }, existingAnswer.workFlowSessionId),
recordId: mergedFromRef?.recordId ?? dataWithoutEndFlag.recordId ?? existingAnswer.recordId,
cardList: mergedFromRef?.cardList ?? (
Array.isArray(dataWithoutEndFlag.cardList) && dataWithoutEndFlag.cardList.length > 0
? dataWithoutEndFlag.cardList
: existingAnswer.cardList
),
isShow: false,
answer: filteredAnswer,
answer: mergedFromRef?.answer ?? filteredAnswer,
workflowParseText: mergedFromRef?.workflowParseText ?? trimSpacesOnly(originalAnswer),
workflowDetectedControl: packetControl ?? mergedFromRef?.workflowDetectedControl,
}
newItems[currentIndex] = {
...newItems[currentIndex],
newItems[lastAiIndex] = {
...newItems[lastAiIndex],
question: isEmptyQuestion ? undefined : question,
answerList: [mergedAnswer],
}
lastStreamedAiAnswerRef.current = {
...mergedAnswer,
workflowParseText: trimSpacesOnly(originalAnswer),
workflowAnswerChunk: answerChunk,
workflowPacketEnd: packetEnd || lastStreamedAiAnswerRef.current?.workflowPacketEnd,
}
}
return newItems
})
......@@ -729,17 +790,20 @@ export const Chat: React.FC = () => {
workflowSilentAppendAiRef.current = isWorkflowSilentSubmit
lastStreamedAiAnswerRef.current = null
activeStreamingAiGroupIdRef.current = null
const isNew = allItems.length <= 1
dispatch(setIsAsking(true))
// 工作流静默续跑:单独追加 AI 占位,避免覆盖上一条(含 JSON 控制指令)的回答
if (isWorkflowSilentSubmit) {
const silentAiGroupId = makeLocalGroupId('ai')
activeStreamingAiGroupIdRef.current = silentAiGroupId
setAllItems(prevItems => [
...prevItems,
{
role: 'ai',
groupId: makeLocalGroupId('ai'),
groupId: silentAiGroupId,
answerList: [{ answer: '', isShow: false }],
} as ChatRecord,
])
......@@ -748,6 +812,8 @@ export const Chat: React.FC = () => {
// 如果 question 不为空,才添加用户问题和空的 AI 回答(静默提问不展示用户气泡)
if (!isEmptyQuestion) {
const questionText = question.trim()
const aiGroupId = makeLocalGroupId('ai')
activeStreamingAiGroupIdRef.current = aiGroupId
setAllItems(prevItems => [
...prevItems,
{
......@@ -757,7 +823,7 @@ export const Chat: React.FC = () => {
} as ChatRecord,
{
role: 'ai',
groupId: makeLocalGroupId('ai'),
groupId: aiGroupId,
question: questionText,
answerList: [{ answer: '', isShow: false }],
} as ChatRecord,
......@@ -902,7 +968,7 @@ export const Chat: React.FC = () => {
// 正常的stream数据
if (msg?.type === 'DATA' && msg?.content?.code === '00000000') {
console.log('========================流式输出====================', msg)
console.log('========================流式输出1111====================', msg)
console.log('========================流式输出字符串====================', msg.content?.data)
handleStreamMesageData(msg, question)
}
......@@ -933,29 +999,40 @@ export const Chat: React.FC = () => {
setAllItems((prevItems) => {
const newItems = [...prevItems]
const streamed = lastStreamedAiAnswerRef.current
for (let i = newItems.length - 1; i >= 0; i--) {
if (newItems[i].role === 'ai' && newItems[i].answerList?.[0]) {
const base = newItems[i].answerList[0]
const streamingGroupId = activeStreamingAiGroupIdRef.current
let mergeAiIndex = -1
if (streamingGroupId) {
mergeAiIndex = newItems.findIndex(
item => item.role === 'ai' && item.groupId === streamingGroupId,
)
}
if (mergeAiIndex < 0)
mergeAiIndex = findLastAiIndex(newItems)
if (mergeAiIndex >= 0 && newItems[mergeAiIndex].role === 'ai' && newItems[mergeAiIndex].answerList?.[0]) {
const i = mergeAiIndex
const base = newItems[i].answerList![0]
const mergedCardList = streamed?.cardList ?? base.cardList
const hasCards = Array.isArray(mergedCardList) && mergedCardList.length > 0
const rawParseText = streamed?.workflowParseText ?? streamed?.answer ?? base.answer ?? ''
const streamParseOptions = buildWorkflowParseOptions(streamed)
const packetQuestion = (streamed as WorkflowStreamAnswer & { question?: string })?.question
const isHiddenRedirect = isHiddenWorkflowRedirectControl(rawParseText, streamParseOptions)
const displayAnswer = resolveDisplayAnswerText(
(streamed?.answer ?? base.answer) === '' ? '' : (streamed?.answer ?? base.answer),
)
const parsedCtrl = parseWorkflowControlForStream(rawParseText, streamParseOptions, packetQuestion)
const isEnterSub = isWorkflowEnterSubPayload(parsedCtrl)
const displayAnswer = resolveDisplayAnswerText(rawParseText, streamParseOptions, packetQuestion)
const merged: Answer = streamed
? {
...base,
...streamed,
answer: isHiddenRedirect
? ''
: (displayAnswer === '' && !hasCards ? '暂无内容' : displayAnswer),
: (displayAnswer === '' && !hasCards && !isEnterSub ? '暂无内容' : displayAnswer),
workFlowSessionId: resolveWorkFlowSessionId(streamed, resolveWorkFlowSessionId(base)),
recordId: streamed.recordId ?? base.recordId,
recordType: streamed.recordType ?? base.recordType,
cardList: mergedCardList,
endAnswerFlag: true,
workflowParseText: rawParseText,
// 含工作流表单卡片时保持 Parser,便于流式过程中展示表单;其余 cardList 流结束后走 Shower
isShow: isHiddenRedirect || (hasCards && hasWorkflowFormCards(mergedCardList))
? false
......@@ -971,6 +1048,7 @@ export const Chat: React.FC = () => {
workflowParseText: rawParseText,
workflowAnswerChunk: streamed?.workflowAnswerChunk,
workflowPacketEnd: streamed?.workflowPacketEnd,
workflowDetectedControl: parsedCtrl ?? streamed?.workflowDetectedControl,
}
if (isHiddenRedirect && !hasCards) {
newItems.splice(i, 1)
......@@ -978,8 +1056,6 @@ export const Chat: React.FC = () => {
else {
newItems[i] = { ...newItems[i], answerList: [merged] }
}
break
}
}
if (!workflowLastAnswer && streamed) {
workflowLastAnswer = {
......@@ -998,9 +1074,14 @@ export const Chat: React.FC = () => {
pendingWorkflowFormSourceKeyRef.current = null
dispatch(setIsAsking(false))
workflowSilentAppendAiRef.current = false
const wfParseText = streamSnapshotForWf?.workflowParseText ?? ''
const wfParseOpts = buildWorkflowParseOptions(streamSnapshotForWf)
const wfParsedCtrl = tryParseWorkflowControlJson(wfParseText, wfParseOpts)
const wfPacketQuestion = (streamSnapshotForWf as WorkflowStreamAnswer & { question?: string })?.question
const wfRawParseText = trimSpacesOnly(
streamSnapshotForWf?.workflowParseText
?? streamSnapshotForWf?.answer
?? '',
)
const wfParsedCtrl = parseWorkflowControlForStream(wfRawParseText, wfParseOpts, wfPacketQuestion)
const wfCtxRecordType = wfParsedCtrl?.recordType != null
? String(wfParsedCtrl.recordType).trim()
: (streamSnapshotForWf?.recordType != null ? String(streamSnapshotForWf.recordType).trim() : '')
......@@ -1012,15 +1093,34 @@ export const Chat: React.FC = () => {
busiType: streamSnapshotForWf?.busiType != null ? String(streamSnapshotForWf.busiType).trim() : '01',
}
}
if (workflowLastAnswer) {
queueMicrotask(() => {
processBusinessInsightWorkflowAfterStream(workflowLastAnswer!)
lastStreamedAiAnswerRef.current = null
const wfAnswerForFollowUp: WorkflowStreamAnswer | null = workflowLastAnswer
?? (streamSnapshotForWf
? {
...streamSnapshotForWf,
endAnswerFlag: true,
workflowDetectedControl: wfParsedCtrl ?? streamSnapshotForWf.workflowDetectedControl,
}
: null)
if (wfAnswerForFollowUp) {
console.log('[Chat WF] 流结束准备续问', {
parsed: wfParsedCtrl,
complete: isWorkflowControlPayloadComplete(wfParsedCtrl),
willEnterSub: isWorkflowEnterSubPayload(wfParsedCtrl),
packetQuestion: wfPacketQuestion,
wfRawParseText: wfRawParseText.slice(0, 120),
hasRef: Boolean(streamSnapshotForWf),
displayAnswer: wfAnswerForFollowUp.answer,
})
processBusinessInsightWorkflowAfterStream(wfAnswerForFollowUp)
}
else {
lastStreamedAiAnswerRef.current = null
console.warn('[Chat WF] 流结束未续问:无 workflow 快照', {
parsed: wfParsedCtrl,
hasRef: Boolean(streamSnapshotForWf),
})
}
lastStreamedAiAnswerRef.current = null
activeStreamingAiGroupIdRef.current = null
if (isNew) {
setTimeout(() => {
dispatch(fetchConversations())
......@@ -1058,6 +1158,7 @@ export const Chat: React.FC = () => {
workflowSilentAppendAiRef.current = false
pendingWorkflowFormSourceKeyRef.current = null
lastStreamedAiAnswerRef.current = null
activeStreamingAiGroupIdRef.current = null
})
}
......@@ -1446,11 +1547,6 @@ export const Chat: React.FC = () => {
const canSend = historyLoadedRef.current.conversationId === currentIdRef.current || allItems.length <= 1
if (canSend) {
const questionToSend = shouldSendQuestion
console.log('[Chat] auto send triggered (shouldSendQuestion):', {
conversationId: currentIdRef.current,
question: questionToSend,
currentToolId,
})
lastSentQuestionRef.current = questionToSend
pendingQuestionRef.current = null
// 立即清除shouldSendQuestion,防止重复发送
......
......@@ -43,7 +43,8 @@ function CheckIcon({ ...props }) {
}
export const ChatAnswerParser: React.FC<ChatAnswerParserProps> = ({ isLastAnswer, onTyping, onComplate, answer, isStopTyping, onSubmitQuestion, hideOperate, onWorkflowSubmit, isWorkflowSubmitting, isAsking = false }) => {
const displayAnswerText = resolveDisplayAnswerText(answer.answer || '')
const answerSourceText = (answer as { workflowParseText?: string }).workflowParseText ?? answer.answer ?? ''
const displayAnswerText = resolveDisplayAnswerText(answerSourceText)
const formatAnswer = formatMarkdown(displayAnswerText)
const hasCards = Array.isArray(answer.cardList) && answer.cardList.length > 0
const [displayedText, setDisplayedText] = useState('')
......@@ -123,6 +124,14 @@ export const ChatAnswerParser: React.FC<ChatAnswerParserProps> = ({ isLastAnswer
}
useEffect(() => {
if (answer.endAnswerFlag) {
setDisplayedText(formatAnswer)
setCurrentIndex(formatAnswer.length)
setIsTyping(false)
}
}, [answer.endAnswerFlag, formatAnswer])
useEffect(() => {
if (isStopTyping) {
return
}
......
......@@ -20,7 +20,8 @@ interface ChatAnswerShowerProps {
export const ChatAnswerShower: React.FC<ChatAnswerShowerProps> = ({ answer, isLastAnswer, onSubmitQuestion, hideOperate: hideOperateProp, onWorkflowSubmit, isWorkflowSubmitting, isAsking = false }) => {
const hideOperateByCard = (answer.cardList || []).some(attachment => attachment.type === 'box' || attachment?.type?.includes('card-'))
const hideOperate = hideOperateByCard || hideOperateProp
const displayAnswerText = resolveDisplayAnswerText(answer.answer || '')
const answerSourceText = (answer as { workflowParseText?: string }).workflowParseText ?? answer.answer ?? ''
const displayAnswerText = resolveDisplayAnswerText(answerSourceText)
const hasCards = Array.isArray(answer.cardList) && answer.cardList.length > 0
// 历史首包静默记录隐藏卡片;流式/含工作流表单卡片需正常展示
const shouldRenderCards = hasCards && !(
......
import { trimSpacesOnly } from './components/ChatItem/markdownFormatter'
import { isWorkflowFormAttachment } from './lib/workflowCardForm'
import type { Answer, Attachment, ChatRecord, OriginalRecord } from '@/types/chat'
......@@ -150,21 +151,38 @@ function parseJsonLevel1(text: string): WorkflowControlPayload | null {
return null
}
function extractQuestionByRegex(text: string): string | undefined {
const quoted = text.match(/"question"\s*:\s*"((?:\\.|[^"\\])*)"/)
if (quoted?.[1]) {
const value = unescapeJsonStringValue(quoted[1]).trim()
if (value)
return value
}
// 兼容非法 JSON:question 未加引号,如 "question":客群洞察
const unquoted = text.match(/"question"\s*:\s*([^,}\]]+)/)
if (unquoted?.[1]) {
const value = unquoted[1].trim().replace(/^["']|["']$/g, '')
if (value)
return value
}
return undefined
}
/** L3:正则提取 recordType / question / end / showFlag */
function extractByRegex(text: string): WorkflowControlPayload | null {
const recordTypeMatch = text.match(/"recordType"\s*:\s*"((?:\\.|[^"\\])*)"/)
const questionMatch = text.match(/"question"\s*:\s*"((?:\\.|[^"\\])*)"/)
const questionFromRegex = extractQuestionByRegex(text)
const endMatch = text.match(/"end"\s*:\s*(true|false|"true"|"false")/i)
const showFlagMatch = text.match(/"showFlag"\s*:\s*(false|true|"false"|"true"|0|1)/i)
if (!recordTypeMatch && !questionMatch && !endMatch)
if (!recordTypeMatch && !questionFromRegex && !endMatch)
return null
const payload: WorkflowControlPayload = {}
if (recordTypeMatch?.[1])
payload.recordType = unescapeJsonStringValue(recordTypeMatch[1]).trim()
if (questionMatch?.[1])
payload.question = unescapeJsonStringValue(questionMatch[1])
if (questionFromRegex)
payload.question = questionFromRegex
if (endMatch?.[1])
payload.end = isWorkflowControlEnd(endMatch[1].replace(/"/g, ''))
if (showFlagMatch?.[1]) {
......@@ -174,6 +192,28 @@ function extractByRegex(text: string): WorkflowControlPayload | null {
return payload
}
/** 合并多段解析结果,优先保留更完整的 recordType / question */
function mergeWorkflowControlPayload(
...parts: Array<WorkflowControlPayload | null | undefined>
): WorkflowControlPayload | null {
const merged: WorkflowControlPayload = {}
for (const part of parts) {
if (!part)
continue
if (part.recordType != null && String(part.recordType).trim())
merged.recordType = String(part.recordType).trim()
if (part.question != null && String(part.question).trim())
merged.question = part.question
if (part.end === true)
merged.end = true
if (part.showFlag !== undefined && part.showFlag !== null)
merged.showFlag = part.showFlag
}
if (!merged.recordType && merged.question == null && merged.end !== true && merged.showFlag == null)
return null
return merged
}
function mergePacketEnd(
payload: WorkflowControlPayload | null,
options?: WorkflowParseOptions,
......@@ -187,19 +227,22 @@ function mergePacketEnd(
function parseWorkflowControlFromText(text: string): WorkflowControlPayload | null {
const candidates = collectParseCandidates(text)
for (let i = candidates.length - 1; i >= 0; i--) {
const candidate = candidates[i]
const level1 = parseJsonLevel1(candidate)
if (level1)
return level1
const level2 = parseJsonLevel1(normalizeEscaped(candidate))
if (level2)
return level2
const level3 = extractByRegex(candidate)
if (level3)
return level3
let best: WorkflowControlPayload | null = null
for (const candidate of candidates) {
const merged = mergeWorkflowControlPayload(
parseJsonLevel1(candidate),
parseJsonLevel1(normalizeEscaped(candidate)),
extractByRegex(candidate),
)
if (!merged)
continue
if (isWorkflowEnterSubPayload(merged) || isHiddenWorkflowRedirectPayload(merged))
return merged
best = mergeWorkflowControlPayload(best, merged)
}
return null
return mergeWorkflowControlPayload(best, extractByRegex(text))
}
/** 兼容 API 返回 workFlowSessionId / workflowSessionId 等字段名 */
......@@ -254,29 +297,222 @@ export function tryParseWorkflowControlJson(text: string, options?: WorkflowPars
return null
}
/** 是否包含工作流表单卡片(card-workflow + form_input,且含 text/select/file 字段) */
export function hasWorkflowFormCards(cardList?: Attachment[]): boolean {
return Array.isArray(cardList) && cardList.some(isWorkflowFormAttachment)
/** 流式分片 answer 可能是 string / 双层 JSON 字符串 / 对象 */
export function normalizeStreamAnswerChunk(raw: unknown): string {
if (raw == null)
return ''
if (typeof raw === 'string')
return raw
if (typeof raw === 'object') {
try {
return JSON.stringify(raw)
}
catch {
return ''
}
}
return String(raw)
}
/** 是否为「进入子工作流」类控制 JSON(解析后含 recordType + question,且非 showFlag 隐藏路由) */
export function isEnterSubWorkflowControlAnswer(text: string, options?: WorkflowParseOptions): boolean {
const parsed = tryParseWorkflowControlJson(text, options)
if (isHiddenWorkflowRedirectPayload(parsed))
/** 是否为「进入子工作流」控制载荷(含 recordType + question,且非隐藏路由) */
export function isWorkflowEnterSubPayload(parsed: WorkflowControlPayload | null | undefined): boolean {
if (!parsed || isHiddenWorkflowRedirectPayload(parsed))
return false
return Boolean(
parsed?.recordType != null
parsed.recordType != null
&& String(parsed.recordType).trim()
&& parsed.question != null,
)
}
/**
* 从流式 AI 回答解析工作流控制 JSON:
* 优先 workflowParseText(原始累积文本),再 answer;解析失败时不用外层 recordType 误代替 answer 内 JSON。
*/
export function resolveWorkflowControlFromStreamAnswer(
snapshot: {
workflowParseText?: string
answer?: string
},
options?: WorkflowParseOptions,
): WorkflowControlPayload | null {
const parseText = trimSpacesOnly(
snapshot.workflowParseText ?? snapshot.answer ?? '',
)
const parsedFromText = parseText
? tryParseWorkflowControlJson(parseText, options)
: null
if (parsedFromText)
return parsedFromText
if (options?.answerChunk?.trim()) {
const chunkText = trimSpacesOnly(normalizeStreamAnswerChunk(options.answerChunk))
if (chunkText)
return tryParseWorkflowControlJson(chunkText, options)
}
return null
}
export function resolveWorkflowControlFromPacketAnswer(
rawAnswer: unknown,
options?: WorkflowParseOptions,
): WorkflowControlPayload | null {
const chunk = normalizeStreamAnswerChunk(rawAnswer)
if (!chunk.trim())
return null
return tryParseWorkflowControlJson(chunk, options)
}
/** 外层 data.question 或累积 answer 文本中的 question 字段,补全控制 JSON */
export function enrichWorkflowControlWithPacketQuestion(
parsed: WorkflowControlPayload | null | undefined,
packetQuestion?: unknown,
parseText?: string,
): WorkflowControlPayload | null {
if (!parsed)
return null
const fromParsed = parsed.question != null ? String(parsed.question).trim() : ''
if (fromParsed)
return parsed
const fromPacket = packetQuestion != null ? String(packetQuestion).trim() : ''
if (fromPacket)
return { ...parsed, question: fromPacket }
const text = parseText?.trim() ?? ''
if (text) {
const fromText = extractQuestionByRegex(text)
if (fromText)
return { ...parsed, question: fromText }
}
return parsed
}
export function isWorkflowControlPayloadComplete(parsed: WorkflowControlPayload | null | undefined): boolean {
if (!parsed)
return false
if (isHiddenWorkflowRedirectPayload(parsed))
return true
return isWorkflowEnterSubPayload(parsed)
}
/**
* 流式 answer 是否为「进子工作流」控制 JSON:
* {"recordType":"A25","question":"客群洞察"}(可选 end / showFlag)
*/
export function isStreamEnterSubWorkflowControlText(
text: string,
options?: WorkflowParseOptions,
packetQuestion?: unknown,
): boolean {
return isWorkflowEnterSubPayload(parseWorkflowControlForStream(text, options, packetQuestion))
}
/**
* 从累积原始文本解析工作流控制 JSON(推荐唯一入口)
* 合并全文/分片 JSON.parse、正则字段、packet.question,且需满足 complete 才返回
*/
export function parseWorkflowControlForStream(
parseText: string,
options?: WorkflowParseOptions,
packetQuestion?: unknown,
): WorkflowControlPayload | null {
const text = trimSpacesOnly(parseText)
if (!text)
return null
const fromText = mergePacketEnd(parseWorkflowControlFromText(text), options)
const fromChunk = options?.answerChunk?.trim()
? mergePacketEnd(parseWorkflowControlFromText(options.answerChunk), options)
: null
const merged = enrichWorkflowControlWithPacketQuestion(
mergeWorkflowControlPayload(fromText, fromChunk, extractByRegex(text)),
packetQuestion,
text,
)
if (merged && isWorkflowControlPayloadComplete(merged))
return merged
return null
}
/**
* 流式快照解析:只信 workflowParseText(原始累积),不用 answer / 历史缓存
*/
export function resolveWorkflowControlFromStreamSnapshot(
snapshot: {
workflowParseText?: string
answer?: string
workflowAnswerChunk?: string
workflowDetectedControl?: WorkflowControlPayload | null
},
options?: WorkflowParseOptions,
packetQuestion?: unknown,
): WorkflowControlPayload | null {
const parseText = trimSpacesOnly(snapshot.workflowParseText ?? '')
if (parseText) {
const parsed = parseWorkflowControlForStream(parseText, options, packetQuestion)
if (parsed)
return parsed
}
const chunkText = trimSpacesOnly(snapshot.workflowAnswerChunk ?? snapshot.answer ?? '')
if (chunkText && chunkText !== parseText) {
const fromChunk = parseWorkflowControlForStream(chunkText, options, packetQuestion)
if (fromChunk)
return fromChunk
}
return null
}
/** 是否包含工作流表单卡片(card-workflow + form_input,且含 text/select/file 字段) */
export function hasWorkflowFormCards(cardList?: Attachment[]): boolean {
return Array.isArray(cardList) && cardList.some(isWorkflowFormAttachment)
}
/** 是否为「进入子工作流」类控制 JSON(解析后含 recordType + question,且非 showFlag 隐藏路由) */
export function isEnterSubWorkflowControlAnswer(text: string, options?: WorkflowParseOptions): boolean {
return isWorkflowEnterSubPayload(resolveWorkflowControlFromStreamAnswer(
{ workflowParseText: text, answer: text },
options,
))
}
/** 从混合正文中移除已识别的工作流控制 JSON,保留其余展示内容 */
export function stripWorkflowControlJsonFromText(text: string, options?: WorkflowParseOptions): string {
const trimmed = text.trim()
if (!trimmed)
return ''
let result = text
for (const segment of splitTopLevelJsonObjects(trimmed)) {
const parsed = parseJsonLevel1(segment)
|| parseJsonLevel1(normalizeEscaped(segment))
|| extractByRegex(segment)
const merged = mergePacketEnd(parsed, options)
if (!merged)
continue
if (isHiddenWorkflowRedirectPayload(merged) || isWorkflowEnterSubPayload(merged))
result = result.split(segment).join('')
}
return trimSpacesOnly(result)
}
/** 工作流控制 JSON 不在气泡中展示正文,仅保留卡片等内容 */
export function resolveDisplayAnswerText(text: string, options?: WorkflowParseOptions): string {
export function resolveDisplayAnswerText(
text: string,
options?: WorkflowParseOptions,
packetQuestion?: unknown,
): string {
if (!text?.trim())
return text || ''
if (isHiddenWorkflowRedirectControl(text, options) || isEnterSubWorkflowControlAnswer(text, options))
const parsed = parseWorkflowControlForStream(text, options, packetQuestion)
if (isHiddenWorkflowRedirectPayload(parsed))
return ''
if (isWorkflowEnterSubPayload(parsed))
return stripWorkflowControlJsonFromText(text, options)
return text
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment