mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
#4220 Parsing the text as markdown and rendering accordingly
This commit is contained in:
parent
853d9b7f98
commit
a1c50b8079
@ -67,6 +67,14 @@ b --> d(The dog in the hog)
|
||||
c --> d
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid">
|
||||
mindmap
|
||||
id1["`Start`"]
|
||||
id2["`Child **with bold** text`"]
|
||||
id3["`Children of which some
|
||||
is using *italic type of* text`"]
|
||||
id4[Child]
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
mindmap
|
||||
id1["`Start
|
||||
second line 😎`"]
|
||||
@ -273,12 +281,14 @@ mindmap
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
startOnLoad: true,
|
||||
logLevel: 5,
|
||||
logLevel: 0,
|
||||
flowchart: {
|
||||
// defaultRenderer: 'elk',
|
||||
useMaxWidth: false,
|
||||
// htmlLabels: false,
|
||||
htmlLabels: true,
|
||||
},
|
||||
htmlLabels: true,
|
||||
gantt: {
|
||||
useMaxWidth: false,
|
||||
},
|
||||
|
@ -53,6 +53,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"@khanacademy/simple-markdown": "^0.8.6",
|
||||
"cytoscape": "^3.23.0",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.1.0",
|
||||
|
@ -33,7 +33,7 @@ export const addNode = (level, id, descr, type) => {
|
||||
id: cnt++,
|
||||
nodeId: sanitizeText(id),
|
||||
level,
|
||||
descr: sanitizeText(descr).replace(/\n/g, '<br />'),
|
||||
descr: sanitizeText(descr),
|
||||
type,
|
||||
children: [],
|
||||
width: getConfig().mindmap.maxNodeWidth,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { select } from 'd3';
|
||||
import * as db from './mindmapDb';
|
||||
import { createText, setSize } from '../../rendering-util/createText';
|
||||
import { createText } from '../../rendering-util/createText';
|
||||
const MAX_SECTIONS = 12;
|
||||
|
||||
/**
|
||||
@ -217,9 +217,8 @@ export const drawNode = function (elem, node, fullSection, conf) {
|
||||
|
||||
// Create the wrapped text element
|
||||
const textElem = nodeElem.append('g');
|
||||
|
||||
const newEl = createText(textElem, node.descr, { useHtmlLabels: htmlLabels });
|
||||
const txt = textElem.node().appendChild(newEl);
|
||||
const newEl = createText(textElem, node.descr, { useHtmlLabels: htmlLabels, width: node.width });
|
||||
// const txt = textElem.node().appendChild(newEl);
|
||||
// const txt = textElem.append(newEl);
|
||||
// const txt = textElem
|
||||
// .append('text')
|
||||
|
@ -3,7 +3,7 @@ import { log } from '../logger';
|
||||
import { getConfig } from '../config';
|
||||
import { evaluate } from '../diagrams/common/common';
|
||||
import { decodeEntities } from '../mermaidAPI';
|
||||
|
||||
import { markdownToHTML, markdownToLines } from '../rendering-util/handle-markdown-text';
|
||||
/**
|
||||
* @param dom
|
||||
* @param styleFn
|
||||
@ -51,51 +51,79 @@ function addHtmlSpan(element, node) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text The text to be wrapped
|
||||
* @param {number} width The max width of the text
|
||||
* Creates a tspan element with the specified attributes for text positioning.
|
||||
*
|
||||
* @param {object} textElement - The parent text element to append the tspan element.
|
||||
* @param {number} lineIndex - The index of the current line in the structuredText array.
|
||||
* @param {number} lineHeight - The line height value for the text.
|
||||
* @returns {object} The created tspan element.
|
||||
*/
|
||||
function wrap(text, width) {
|
||||
text.each(function () {
|
||||
var text = select(this),
|
||||
words = text
|
||||
.text()
|
||||
.split(/(\s+|<br\/>)/)
|
||||
.reverse(),
|
||||
word,
|
||||
line = [],
|
||||
lineHeight = 1.1, // ems
|
||||
y = text.attr('y'),
|
||||
dy = parseFloat(text.attr('dy')),
|
||||
tspan = text
|
||||
.text(null)
|
||||
.append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', y)
|
||||
.attr('dy', dy + 'em');
|
||||
for (let j = 0; j < words.length; j++) {
|
||||
word = words[words.length - 1 - j];
|
||||
line.push(word);
|
||||
tspan.text(line.join(' ').trim());
|
||||
if (tspan.node().getComputedTextLength() > width || word === '<br/>') {
|
||||
line.pop();
|
||||
tspan.text(line.join(' ').trim());
|
||||
if (word === '<br/>') {
|
||||
line = [''];
|
||||
} else {
|
||||
line = [word];
|
||||
}
|
||||
function createTspan(textElement, lineIndex, lineHeight) {
|
||||
return textElement
|
||||
.append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', lineIndex * lineHeight + 'em')
|
||||
.attr('dy', lineHeight + 'em');
|
||||
}
|
||||
|
||||
tspan = text
|
||||
.append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', y)
|
||||
.attr('dy', lineHeight + 'em')
|
||||
.text(word);
|
||||
/**
|
||||
* Creates a formatted text element by breaking lines and applying styles based on
|
||||
* the given structuredText.
|
||||
*
|
||||
* @param {number} width - The maximum allowed width of the text.
|
||||
* @param {object} g - The parent group element to append the formatted text.
|
||||
* @param {Array} structuredText - The structured text data to format.
|
||||
*/
|
||||
function createFormattedText(width, g, structuredText) {
|
||||
const lineHeight = 1.1;
|
||||
|
||||
const textElement = g.append('text');
|
||||
|
||||
structuredText.forEach((line, lineIndex) => {
|
||||
let tspan = createTspan(textElement, lineIndex, lineHeight);
|
||||
|
||||
let words = [...line].reverse();
|
||||
let currentWord;
|
||||
let wrappedLine = [];
|
||||
|
||||
while (words.length) {
|
||||
currentWord = words.pop();
|
||||
wrappedLine.push(currentWord);
|
||||
|
||||
updateTextContentAndStyles(tspan, wrappedLine);
|
||||
|
||||
if (tspan.node().getComputedTextLength() > width) {
|
||||
wrappedLine.pop();
|
||||
words.push(currentWord);
|
||||
|
||||
updateTextContentAndStyles(tspan, wrappedLine);
|
||||
|
||||
wrappedLine = [];
|
||||
tspan = createTspan(textElement, ++lineIndex, lineHeight);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the text content and styles of the given tspan element based on the
|
||||
* provided wrappedLine data.
|
||||
*
|
||||
* @param {object} tspan - The tspan element to update.
|
||||
* @param {Array} wrappedLine - The line data to apply to the tspan element.
|
||||
*/
|
||||
function updateTextContentAndStyles(tspan, wrappedLine) {
|
||||
tspan.text('');
|
||||
|
||||
wrappedLine.forEach((word) => {
|
||||
tspan
|
||||
.append('tspan')
|
||||
.attr('font-style', word.type === 'em' ? 'italic' : 'normal')
|
||||
.attr('font-weight', word.type === 'strong' ? 'bold' : 'normal')
|
||||
.text(word.content + ' ');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param el
|
||||
@ -114,15 +142,17 @@ function wrap(text, width) {
|
||||
export const createText = (
|
||||
el,
|
||||
text = '',
|
||||
{ style = '', isTitle = false, classes = '', useHtmlLabels = true, isNode = true } = {}
|
||||
{ style = '', isTitle = false, classes = '', useHtmlLabels = true, isNode = true, width } = {}
|
||||
) => {
|
||||
log.info('createText', text, style, isTitle, classes, useHtmlLabels, isNode);
|
||||
if (useHtmlLabels) {
|
||||
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
|
||||
text = text.replace(/\\n|\n/g, '<br />');
|
||||
log.info('text' + text);
|
||||
// text = text.replace(/\\n|\n/g, '<br />');
|
||||
const htmlText = markdownToHTML(text);
|
||||
// log.info('markdo wnToHTML' + text, markdownToHTML(text));
|
||||
const node = {
|
||||
isNode,
|
||||
label: decodeEntities(text).replace(
|
||||
label: decodeEntities(htmlText).replace(
|
||||
/fa[blrs]?:fa-[\w-]+/g,
|
||||
(s) => `<i class='${s.replace(':', ' ')}'></i>`
|
||||
),
|
||||
@ -131,31 +161,7 @@ export const createText = (
|
||||
let vertexNode = addHtmlSpan(el, node);
|
||||
return vertexNode;
|
||||
} else {
|
||||
const svgText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
svgText.setAttribute('style', style.replace('color:', 'fill:'));
|
||||
// el.attr('style', style.replace('color:', 'fill:'));
|
||||
let rows = [];
|
||||
if (typeof text === 'string') {
|
||||
rows = text.split(/\\n|\n|<br\s*\/?>/gi);
|
||||
} else if (Array.isArray(text)) {
|
||||
rows = text;
|
||||
} else {
|
||||
rows = [];
|
||||
}
|
||||
|
||||
for (const row of rows) {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
|
||||
tspan.setAttribute('dy', '1em');
|
||||
tspan.setAttribute('x', '0');
|
||||
if (isTitle) {
|
||||
tspan.setAttribute('class', 'title-row');
|
||||
} else {
|
||||
tspan.setAttribute('class', 'row');
|
||||
}
|
||||
tspan.textContent = row.trim();
|
||||
svgText.appendChild(tspan);
|
||||
}
|
||||
return svgText;
|
||||
const structuredText = markdownToLines(text);
|
||||
return createFormattedText(width, el, structuredText);
|
||||
}
|
||||
};
|
||||
|
78
packages/mermaid/src/rendering-util/handle-markdown-text.js
Normal file
78
packages/mermaid/src/rendering-util/handle-markdown-text.js
Normal file
@ -0,0 +1,78 @@
|
||||
import SimpleMarkdown from '@khanacademy/simple-markdown';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param markdown
|
||||
*/
|
||||
export function markdownToLines(markdown) {
|
||||
const mdParse = SimpleMarkdown.defaultBlockParse;
|
||||
const syntaxTree = mdParse(markdown);
|
||||
|
||||
let lines = [[]];
|
||||
let currentLine = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param node
|
||||
* @param parentType
|
||||
*/
|
||||
function processNode(node, parentType) {
|
||||
if (node.type === 'text') {
|
||||
const textLines = node.content.split('\n');
|
||||
textLines.forEach((textLine, index) => {
|
||||
if (index !== 0) {
|
||||
currentLine++;
|
||||
lines.push([]);
|
||||
}
|
||||
textLine.split(' ').forEach((word) => {
|
||||
if (word) {
|
||||
lines[currentLine].push({ content: word, type: parentType || 'normal' });
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (node.type === 'strong' || node.type === 'em') {
|
||||
node.content.forEach((contentNode) => {
|
||||
processNode(contentNode, node.type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
syntaxTree.forEach((treeNode) => {
|
||||
if (treeNode.type === 'paragraph') {
|
||||
treeNode.content.forEach((contentNode) => {
|
||||
processNode(contentNode);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param markdown
|
||||
*/
|
||||
export function markdownToHTML(markdown) {
|
||||
const mdParse = SimpleMarkdown.defaultBlockParse;
|
||||
const syntaxTree = mdParse(markdown);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
function output(node) {
|
||||
if (node.type === 'text') {
|
||||
return node.content.replace(/\n/g, '<br>');
|
||||
} else if (node.type === 'strong') {
|
||||
return `<strong>${node.content.map(output).join('')}</strong>`;
|
||||
} else if (node.type === 'em') {
|
||||
return `<em>${node.content.map(output).join('')}</em>`;
|
||||
} else if (node.type === 'paragraph') {
|
||||
return `<p>${node.content.map(output).join('')}</p>`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return syntaxTree.map(output).join('');
|
||||
}
|
181
packages/mermaid/src/rendering-util/handle-markdown-text.spec.js
Normal file
181
packages/mermaid/src/rendering-util/handle-markdown-text.spec.js
Normal file
@ -0,0 +1,181 @@
|
||||
// import { test } from 'vitest';
|
||||
import { markdownToLines, markdownToHTML } from './handle-markdown-text';
|
||||
import { test } from 'vitest';
|
||||
|
||||
test('markdownToLines - Basic test', () => {
|
||||
const input = `This is regular text
|
||||
Here is a new line
|
||||
There is some words **with a bold** section
|
||||
Here is a line *with an italic* section`;
|
||||
|
||||
const expectedOutput = [
|
||||
[
|
||||
{ content: 'This', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'regular', type: 'normal' },
|
||||
{ content: 'text', type: 'normal' },
|
||||
],
|
||||
[
|
||||
{ content: 'Here', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'a', type: 'normal' },
|
||||
{ content: 'new', type: 'normal' },
|
||||
{ content: 'line', type: 'normal' },
|
||||
],
|
||||
[
|
||||
{ content: 'There', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'some', type: 'normal' },
|
||||
{ content: 'words', type: 'normal' },
|
||||
{ content: 'with', type: 'strong' },
|
||||
{ content: 'a', type: 'strong' },
|
||||
{ content: 'bold', type: 'strong' },
|
||||
{ content: 'section', type: 'normal' },
|
||||
],
|
||||
[
|
||||
{ content: 'Here', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'a', type: 'normal' },
|
||||
{ content: 'line', type: 'normal' },
|
||||
{ content: 'with', type: 'em' },
|
||||
{ content: 'an', type: 'em' },
|
||||
{ content: 'italic', type: 'em' },
|
||||
{ content: 'section', type: 'normal' },
|
||||
],
|
||||
];
|
||||
|
||||
const output = markdownToLines(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToLines - Empty input', () => {
|
||||
const input = '';
|
||||
const expectedOutput = [[]];
|
||||
const output = markdownToLines(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToLines - No formatting', () => {
|
||||
const input = `This is a simple test
|
||||
with no formatting`;
|
||||
|
||||
const expectedOutput = [
|
||||
[
|
||||
{ content: 'This', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'a', type: 'normal' },
|
||||
{ content: 'simple', type: 'normal' },
|
||||
{ content: 'test', type: 'normal' },
|
||||
],
|
||||
[
|
||||
{ content: 'with', type: 'normal' },
|
||||
{ content: 'no', type: 'normal' },
|
||||
{ content: 'formatting', type: 'normal' },
|
||||
],
|
||||
];
|
||||
|
||||
const output = markdownToLines(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToLines - Only bold formatting', () => {
|
||||
const input = `This is a **bold** test`;
|
||||
|
||||
const expectedOutput = [
|
||||
[
|
||||
{ content: 'This', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'a', type: 'normal' },
|
||||
{ content: 'bold', type: 'strong' },
|
||||
{ content: 'test', type: 'normal' },
|
||||
],
|
||||
];
|
||||
|
||||
const output = markdownToLines(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToLines - Only italic formatting', () => {
|
||||
const input = `This is an *italic* test`;
|
||||
|
||||
const expectedOutput = [
|
||||
[
|
||||
{ content: 'This', type: 'normal' },
|
||||
{ content: 'is', type: 'normal' },
|
||||
{ content: 'an', type: 'normal' },
|
||||
{ content: 'italic', type: 'em' },
|
||||
{ content: 'test', type: 'normal' },
|
||||
],
|
||||
];
|
||||
|
||||
const output = markdownToLines(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
it('markdownToLines - Mixed formatting', () => {
|
||||
const input = `*Italic* and **bold** formatting`;
|
||||
|
||||
const expectedOutput = [
|
||||
[
|
||||
{ content: 'Italic', type: 'em' },
|
||||
{ content: 'and', type: 'normal' },
|
||||
{ content: 'bold', type: 'strong' },
|
||||
{ content: 'formatting', type: 'normal' },
|
||||
],
|
||||
];
|
||||
|
||||
const output = markdownToLines(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToHTML - Basic test', () => {
|
||||
const input = `This is regular text
|
||||
Here is a new line
|
||||
There is some words **with a bold** section
|
||||
Here is a line *with an italic* section`;
|
||||
|
||||
const expectedOutput = `<p>This is regular text<br>Here is a new line<br>There is some words <strong>with a bold</strong> section<br>Here is a line <em>with an italic</em> section</p>`;
|
||||
|
||||
const output = markdownToHTML(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToHTML - Empty input', () => {
|
||||
const input = '';
|
||||
const expectedOutput = '';
|
||||
const output = markdownToHTML(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToHTML - No formatting', () => {
|
||||
const input = `This is a simple test
|
||||
with no formatting`;
|
||||
|
||||
const expectedOutput = `<p>This is a simple test<br>with no formatting</p>`;
|
||||
const output = markdownToHTML(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToHTML - Only bold formatting', () => {
|
||||
const input = `This is a **bold** test`;
|
||||
|
||||
const expectedOutput = `<p>This is a <strong>bold</strong> test</p>`;
|
||||
const output = markdownToHTML(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToHTML - Only italic formatting', () => {
|
||||
const input = `This is an *italic* test`;
|
||||
|
||||
const expectedOutput = `<p>This is an <em>italic</em> test</p>`;
|
||||
const output = markdownToHTML(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
||||
|
||||
test('markdownToHTML - Mixed formatting', () => {
|
||||
const input = `*Italic* and **bold** formatting`;
|
||||
|
||||
const expectedOutput = `<p><em>Italic</em> and <strong>bold</strong> formatting</p>`;
|
||||
const output = markdownToHTML(input);
|
||||
expect(output).toEqual(expectedOutput);
|
||||
});
|
93
pnpm-lock.yaml
generated
93
pnpm-lock.yaml
generated
@ -178,6 +178,9 @@ importers:
|
||||
'@braintree/sanitize-url':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
'@khanacademy/simple-markdown':
|
||||
specifier: ^0.8.6
|
||||
version: 0.8.6_wcqkhtmu7mswc6yz4uyexck3ty
|
||||
cytoscape:
|
||||
specifier: ^3.23.0
|
||||
version: 3.23.0
|
||||
@ -322,7 +325,7 @@ importers:
|
||||
version: 1.0.0
|
||||
vitepress:
|
||||
specifier: ^1.0.0-alpha.46
|
||||
version: 1.0.0-alpha.46_tbpndr44ulefs3hehwpi2mkf2y
|
||||
version: 1.0.0-alpha.46_hoyvfk3ab7nzsjkhptt6ai7rzq
|
||||
vitepress-plugin-search:
|
||||
specifier: ^1.0.4-alpha.19
|
||||
version: 1.0.4-alpha.19_g67lr3vgasogkevpbew55lljzq
|
||||
@ -1705,10 +1708,10 @@ packages:
|
||||
resolution: {integrity: sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==}
|
||||
dev: true
|
||||
|
||||
/@docsearch/js/3.3.3_tbpndr44ulefs3hehwpi2mkf2y:
|
||||
/@docsearch/js/3.3.3_hoyvfk3ab7nzsjkhptt6ai7rzq:
|
||||
resolution: {integrity: sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==}
|
||||
dependencies:
|
||||
'@docsearch/react': 3.3.3_tbpndr44ulefs3hehwpi2mkf2y
|
||||
'@docsearch/react': 3.3.3_hoyvfk3ab7nzsjkhptt6ai7rzq
|
||||
preact: 10.11.0
|
||||
transitivePeerDependencies:
|
||||
- '@algolia/client-search'
|
||||
@ -1717,7 +1720,7 @@ packages:
|
||||
- react-dom
|
||||
dev: true
|
||||
|
||||
/@docsearch/react/3.3.3_tbpndr44ulefs3hehwpi2mkf2y:
|
||||
/@docsearch/react/3.3.3_hoyvfk3ab7nzsjkhptt6ai7rzq:
|
||||
resolution: {integrity: sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==}
|
||||
peerDependencies:
|
||||
'@types/react': '>= 16.8.0 < 19.0.0'
|
||||
@ -1735,6 +1738,8 @@ packages:
|
||||
'@algolia/autocomplete-preset-algolia': 1.7.4_qs6lk5nhygj2o3hj4sf6xnr724
|
||||
'@docsearch/css': 3.3.3
|
||||
algoliasearch: 4.14.2
|
||||
react: 16.14.0
|
||||
react-dom: 16.14.0_react@16.14.0
|
||||
transitivePeerDependencies:
|
||||
- '@algolia/client-search'
|
||||
dev: true
|
||||
@ -2464,6 +2469,17 @@ packages:
|
||||
'@jridgewell/sourcemap-codec': 1.4.14
|
||||
dev: true
|
||||
|
||||
/@khanacademy/simple-markdown/0.8.6_wcqkhtmu7mswc6yz4uyexck3ty:
|
||||
resolution: {integrity: sha512-mAUlR9lchzfqunR89pFvNI51jQKsMpJeWYsYWw0DQcUXczn/T/V6510utgvm7X0N3zN87j1SvuKk8cMbl9IAFw==}
|
||||
peerDependencies:
|
||||
react: 16.14.0
|
||||
react-dom: 16.14.0
|
||||
dependencies:
|
||||
'@types/react': 18.0.28
|
||||
react: 16.14.0
|
||||
react-dom: 16.14.0_react@16.14.0
|
||||
dev: false
|
||||
|
||||
/@leichtgewicht/ip-codec/2.0.4:
|
||||
resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==}
|
||||
dev: true
|
||||
@ -3047,6 +3063,10 @@ packages:
|
||||
resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==}
|
||||
dev: true
|
||||
|
||||
/@types/prop-types/15.7.5:
|
||||
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
|
||||
dev: false
|
||||
|
||||
/@types/qs/6.9.7:
|
||||
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
|
||||
dev: true
|
||||
@ -3055,6 +3075,14 @@ packages:
|
||||
resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
|
||||
dev: true
|
||||
|
||||
/@types/react/18.0.28:
|
||||
resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==}
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.5
|
||||
'@types/scheduler': 0.16.2
|
||||
csstype: 3.1.1
|
||||
dev: false
|
||||
|
||||
/@types/responselike/1.0.0:
|
||||
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
|
||||
dependencies:
|
||||
@ -3072,6 +3100,10 @@ packages:
|
||||
rollup: 2.79.1
|
||||
dev: true
|
||||
|
||||
/@types/scheduler/0.16.2:
|
||||
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
|
||||
dev: false
|
||||
|
||||
/@types/semver/7.3.12:
|
||||
resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==}
|
||||
dev: true
|
||||
@ -5248,6 +5280,10 @@ packages:
|
||||
resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
|
||||
dev: true
|
||||
|
||||
/csstype/3.1.1:
|
||||
resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
|
||||
dev: false
|
||||
|
||||
/cypress-image-snapshot/4.0.1_cypress@12.5.1+jest@29.3.1:
|
||||
resolution: {integrity: sha512-PBpnhX/XItlx3/DAk5ozsXQHUi72exybBNH5Mpqj1DVmjq+S5Jd9WE5CRa4q5q0zuMZb2V2VpXHth6MjFpgj9Q==}
|
||||
engines: {node: '>=8'}
|
||||
@ -8213,7 +8249,6 @@ packages:
|
||||
|
||||
/js-tokens/4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: true
|
||||
|
||||
/js-yaml/3.14.1:
|
||||
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
|
||||
@ -8621,6 +8656,12 @@ packages:
|
||||
resolution: {integrity: sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==}
|
||||
dev: true
|
||||
|
||||
/loose-envify/1.4.0:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
/loupe/2.3.6:
|
||||
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
|
||||
dependencies:
|
||||
@ -9432,7 +9473,6 @@ packages:
|
||||
/object-assign/4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/object-inspect/1.12.2:
|
||||
resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==}
|
||||
@ -9943,6 +9983,13 @@ packages:
|
||||
sisteransi: 1.0.5
|
||||
dev: true
|
||||
|
||||
/prop-types/15.8.1:
|
||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
react-is: 16.13.1
|
||||
|
||||
/proxy-addr/2.0.7:
|
||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
@ -10055,6 +10102,20 @@ packages:
|
||||
unpipe: 1.0.0
|
||||
dev: true
|
||||
|
||||
/react-dom/16.14.0_react@16.14.0:
|
||||
resolution: {integrity: sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==}
|
||||
peerDependencies:
|
||||
react: ^16.14.0
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 16.14.0
|
||||
scheduler: 0.19.1
|
||||
|
||||
/react-is/16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
/react-is/17.0.2:
|
||||
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||
dev: true
|
||||
@ -10063,6 +10124,14 @@ packages:
|
||||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||
dev: true
|
||||
|
||||
/react/16.14.0:
|
||||
resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
prop-types: 15.8.1
|
||||
|
||||
/read-pkg-up/7.0.1:
|
||||
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
|
||||
engines: {node: '>=8'}
|
||||
@ -10471,6 +10540,12 @@ packages:
|
||||
xmlchars: 2.2.0
|
||||
dev: true
|
||||
|
||||
/scheduler/0.19.1:
|
||||
resolution: {integrity: sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
|
||||
/schema-utils/3.1.1:
|
||||
resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
@ -11769,16 +11844,16 @@ packages:
|
||||
'@types/markdown-it': 12.2.3
|
||||
flexsearch: 0.7.31
|
||||
markdown-it: 13.0.1
|
||||
vitepress: 1.0.0-alpha.46_tbpndr44ulefs3hehwpi2mkf2y
|
||||
vitepress: 1.0.0-alpha.46_hoyvfk3ab7nzsjkhptt6ai7rzq
|
||||
vue: 3.2.45
|
||||
dev: true
|
||||
|
||||
/vitepress/1.0.0-alpha.46_tbpndr44ulefs3hehwpi2mkf2y:
|
||||
/vitepress/1.0.0-alpha.46_hoyvfk3ab7nzsjkhptt6ai7rzq:
|
||||
resolution: {integrity: sha512-HiKiHzC0iTPsRsKs8XcsMeMzCpcCt5LWcX9mpDr288Ju+nQf1G8A2+Wm44ZkBsVv4EHxFK4ChmWyZrL1OJUXpg==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@docsearch/css': 3.3.3
|
||||
'@docsearch/js': 3.3.3_tbpndr44ulefs3hehwpi2mkf2y
|
||||
'@docsearch/js': 3.3.3_hoyvfk3ab7nzsjkhptt6ai7rzq
|
||||
'@vitejs/plugin-vue': 4.0.0_vite@4.1.1+vue@3.2.45
|
||||
'@vue/devtools-api': 6.5.0
|
||||
'@vueuse/core': 9.12.0_vue@3.2.45
|
||||
|
Loading…
x
Reference in New Issue
Block a user