- {content}
- {term &&
More Info }
+ const [showTooltip, setShowTooltip] = useState(false);
+ let processedTermName = termName
+ ? processText(termName)
+ : processText(children);
+
+ const term = glossaryData.find(
+ (term) => processText(term.label) === processedTermName,
+ );
+
+ const content = term ? term.summary || term.description : "";
+
+ return (
+
setShowTooltip(true)}
+ onMouseLeave={() => setShowTooltip(false)}
+ >
+ {children}
+
+
- );
+ );
};
export default Tooltip;
diff --git a/src/components/glossary/tool-tip/styles.module.scss b/src/components/glossary/tool-tip/styles.module.scss
index 7939590185e..709692aec55 100644
--- a/src/components/glossary/tool-tip/styles.module.scss
+++ b/src/components/glossary/tool-tip/styles.module.scss
@@ -18,7 +18,9 @@
z-index: 100;
opacity: 0;
visibility: hidden;
- transition: visibility 0.2s, opacity 0.2s ease-in-out;
+ transition:
+ visibility 0.2s,
+ opacity 0.2s ease-in-out;
background-color: var(--custom-surface-color);
color: var(--ifm-font-color-base);
text-decoration: none;
diff --git a/src/components/graphs/bar/index.jsx b/src/components/graphs/bar/index.jsx
new file mode 100644
index 00000000000..13ab8c8abca
--- /dev/null
+++ b/src/components/graphs/bar/index.jsx
@@ -0,0 +1,170 @@
+import React from "react";
+
+const NeuralMagicBar = ({
+ children,
+ file,
+ data,
+ testDataType = null,
+ width = "100%",
+ height = "400px",
+ title = null,
+ titleType = "h2",
+ subTitle = null,
+ subTitleType = "h6",
+ showLegend = true,
+ valuesLabel = null,
+ valuesFormat = "#",
+ valueMax = null,
+ valueMin = null,
+ valueStepPercentage = 33.33,
+ valueSteps = null,
+ groupsLabel = null,
+}) => {
+ return
NeuralMagicBar
;
+
+ // if (testDataType) {
+ // data = samples["bar"][testDataType];
+ // }
+ //
+ // const dataSeries = [];
+ // const dataLabels = [];
+ // let colorIndex = 0;
+ //
+ // for (const { value, label, index = null } of data) {
+ // let series = dataSeries.find((series) => series.index === index);
+ //
+ // if (!series) {
+ // series = {
+ // index,
+ // color: styling.colors[colorIndex % styling.colors.length],
+ // };
+ // dataSeries.push(series);
+ // colorIndex += 1;
+ // }
+ //
+ // let dataLabel = dataLabels.find((dataLabel) => dataLabel.label === label);
+ //
+ // if (!dataLabel) {
+ // dataLabel = { label, values: [] };
+ // dataLabels.push(dataLabel);
+ // }
+ //
+ // dataLabel.values.push({ value, color: series.color });
+ // }
+ //
+ // const dataValueMin = Math.min(...data.map((item) => item.value)) * 0.9;
+ // const dataValueMax = Math.max(...data.map((item) => item.value)) * 1.1;
+ // const verticalAxisMax = valueMax === null ? dataValueMax : valueMax;
+ // const verticalAxisMin = valueMin === null ? dataValueMin : valueMin;
+ // const verticalAxisStrata = [];
+ //
+ // if (!valueSteps) {
+ // for (
+ // let percentIncrement = 0;
+ // percentIncrement <= 100;
+ // percentIncrement += valueStepPercentage
+ // ) {
+ // verticalAxisStrata.push(
+ // verticalAxisMin +
+ // (verticalAxisMax - verticalAxisMin) * (percentIncrement / 100),
+ // );
+ // }
+ // } else {
+ // verticalAxisStrata.push(...valueSteps);
+ // }
+ //
+ // const maxBarsPerLabel = Math.max(
+ // ...dataLabels.map((label) => label.values.length),
+ // );
+ //
+ // return (
+ //
+ // {(title || subTitle) && (
+ //
+ // {title &&
+ // React.createElement(titleType, { className: styles.title }, title)}
+ // {subTitle &&
+ // React.createElement(
+ // subTitleType,
+ // { className: styles.subTitle },
+ // subTitle,
+ // )}
+ //
+ //
+ //
+ // )}
+ //
+ //
+ // {showLegend && (
+ //
+ // {dataSeries.map((series) => (
+ //
+ //
+ //
{series.index}
+ //
+ // ))}
+ //
+ // )}
+ //
+ //
+ //
+ // {valuesLabel && (
+ //
+ //
+ //
+ // {verticalAxisStrata.map((value) => (
+ //
+ // {formatValue(value, valuesFormat)}
+ //
+ // ))}
+ //
+ //
+ // )}
+ //
+ //
+ // {dataLabels.map((label) => (
+ //
+ // {label.values.map((value) => (
+ //
+ // ))}
+ //
+ // ))}
+ //
+ //
+ //
+ //
+ // {dataLabels.map((label) => (
+ //
+ // {label.label}
+ //
+ // ))}
+ //
+ //
+ //
+ // {groupsLabel && (
+ //
+ // )}
+ //
+ //
+ // );
+};
+
+export default NeuralMagicBar;
diff --git a/src/components/graphs/data.jsx b/src/components/graphs/data.jsx
new file mode 100644
index 00000000000..2f65ec246ae
--- /dev/null
+++ b/src/components/graphs/data.jsx
@@ -0,0 +1,90 @@
+const dataSamples = {
+ bar: {
+ sample: [
+ { index: "FP16 Baseline", label: "Dense", value: 14.9 },
+ { index: "INT8 Weights & Activations", label: "Dense", value: 6.7 },
+ {
+ index: "INT8 Weights & Activations",
+ label: "50% Sparsity",
+ value: 5.1,
+ },
+ {
+ index: "INT8 Weights & Activations",
+ label: "70% Sparsity",
+ value: 3.9,
+ },
+ { index: "INT4 Weights", label: "Dense", value: 5.1 },
+ ],
+ },
+ line: {
+ sample: [
+ { index: "FP16 Baseline", label: 5.6, value: 14.9 },
+ { index: "INT8 Weights & Activations", label: 10.3, value: 6.7 },
+ { index: "INT8 Weights & Activations", label: 8.7, value: 5.1 },
+ { index: "INT8 Weights & Activations", label: 3.2, value: 3.9 },
+ { index: "INT4 Weights", label: 2.1, value: 5.1 },
+ ],
+ },
+};
+
+const formatData = ({ data, indexColors, colorShift = 0 }) => {
+ const indices = [];
+ const labels = [];
+ let colorIndex = 0;
+
+ for (const { value, label, index = null } of data) {
+ let dataSeries = indices.find((series) => series.index === index);
+ if (!dataSeries) {
+ dataSeries = {
+ index,
+ color: indexColors[(colorIndex + colorShift) % indexColors.length],
+ data: [],
+ };
+ indices.push(dataSeries);
+ colorIndex += 1;
+ }
+ dataSeries.data.push({ index, label, value, color: dataSeries.color });
+
+ let dataLabel = labels.find((dataLabel) => dataLabel.label === label);
+ if (!dataLabel) {
+ dataLabel = { label, data: [] };
+ labels.push(dataLabel);
+ }
+ dataLabel.data.push({ index, label, value, color: dataSeries.color });
+ }
+
+ return {
+ data,
+ indices,
+ labels,
+ };
+};
+
+const extractData = ({
+ data,
+ children,
+ file,
+ testDataType,
+ chartType,
+ indexColors,
+ colorShift,
+}) => {
+ // format the data to use
+ let extracted = data;
+
+ if (children) {
+ throw new Error("Children are not supported for this component.");
+ }
+
+ if (file) {
+ throw new Error("File is not supported for this component.");
+ }
+
+ if (testDataType) {
+ extracted = dataSamples[chartType][testDataType];
+ }
+
+ return formatData({ data: extracted, indexColors, colorShift });
+};
+
+export { dataSamples, formatData, extractData };
diff --git a/src/components/graphs/graphs.svg.jsx b/src/components/graphs/graphs.svg.jsx
new file mode 100644
index 00000000000..2b385b84e66
--- /dev/null
+++ b/src/components/graphs/graphs.svg.jsx
@@ -0,0 +1,765 @@
+import { createText, pointsToPathD } from "./svg";
+import { Point, Rectangle } from "./vector";
+import { hashObjects, stringFormat, textDimensions } from "./utilities";
+
+const createBackground = ({
+ width,
+ height,
+ bottomHeading,
+ headingMargin = 0,
+ cornerRadius = 16,
+ color = "white",
+ borderColor = "white",
+ borderWidth = 0,
+ stylePulltab = false,
+ pullTabGap = 12,
+ pullTabInset = 32,
+}) => {
+ const key = hashObjects({
+ width,
+ height,
+ bottomHeading,
+ cornerRadius,
+ color,
+ borderColor,
+ borderWidth,
+ stylePulltab,
+ pullTabGap,
+ pullTabInset,
+ });
+
+ if (!stylePulltab) {
+ const backgroundRect = (
+
+ );
+
+ return {
+ elements: [backgroundRect],
+ dimensions: new Rectangle(0, 0, width, height),
+ graphTop: bottomHeading + headingMargin,
+ };
+ }
+
+ const pullTabMeasurements = {
+ top: 0,
+ bottom: bottomHeading + headingMargin,
+ left: 0,
+ leftInset: pullTabInset,
+ right: width,
+ rightInset: width - pullTabInset,
+ };
+ const graphRectMeasurements = {
+ top: bottomHeading + headingMargin + pullTabGap,
+ bottom: height,
+ left: 0,
+ right: width,
+ };
+
+ const backgroundPath = (
+
+ );
+
+ return {
+ elements: [backgroundPath],
+ dimensions: new Rectangle(0, 0, width, height),
+ graphTop: graphRectMeasurements.top + headingMargin,
+ };
+};
+
+const createGraphBackground = ({
+ anchorPoint,
+ width,
+ height,
+ color = "white",
+ cornerRadius = 16,
+ borderColor = "white",
+ borderWidth = 0,
+ verticalAxisSide = "", // "start" or "end" (left or right)
+ horizontalAxisSide = "", // "start" or "end" (top or bottom)
+}) => {
+ const cornersRadii = [
+ verticalAxisSide !== "start" && horizontalAxisSide !== "start"
+ ? cornerRadius
+ : 0, // top left
+ verticalAxisSide !== "end" && horizontalAxisSide !== "start"
+ ? cornerRadius
+ : 0, // top right
+ verticalAxisSide !== "end" && horizontalAxisSide !== "end"
+ ? cornerRadius
+ : 0, // bottom right
+ verticalAxisSide !== "start" && horizontalAxisSide !== "end"
+ ? cornerRadius
+ : 0, // bottom left
+ ];
+ const elements = [
+
,
+ ];
+
+ return {
+ elements,
+ dimensions: new Rectangle(anchorPoint.x, anchorPoint.y, width, height),
+ };
+};
+
+const createHeading = ({
+ xPosition,
+ yPosition,
+ width,
+ align = "left", // "left", "center", "right"
+ title = null,
+ titleType = "h2",
+ titleColor = "black",
+ titlesSpacing = 8,
+ subTitle = null,
+ subTitleType = "h6",
+ subTitleColor = "grey",
+}) => {
+ if (xPosition === null || xPosition === undefined) {
+ throw new Error("Invalid xPosition");
+ }
+
+ if (width === null || width === undefined) {
+ throw new Error("Invalid width");
+ }
+
+ if (yPosition === null || yPosition === undefined) {
+ throw new Error("Invalid yPosition");
+ }
+
+ if (["left", "center", "right"].indexOf(align) === -1) {
+ throw new Error(`Invalid align: ${align}`);
+ }
+
+ const boundsStart = new Point(xPosition, yPosition);
+ const boundsEnd = new Point(xPosition + width, yPosition);
+ let textAnchor;
+ let textAlignment;
+
+ if (align === "left") {
+ textAnchor = new Point(boundsStart.x, boundsStart.y);
+ textAlignment = "start";
+ } else if (align === "center") {
+ textAnchor = new Point(boundsStart.x + width / 2, boundsStart.y);
+ textAlignment = "middle";
+ } else if (align === "right") {
+ textAnchor = new Point(boundsEnd.x, boundsStart.y);
+ textAlignment = "end";
+ }
+
+ const elements = [];
+
+ if (title) {
+ const titleText = createText({
+ text: title,
+ style: titleType,
+ anchorPoint: textAnchor,
+ color: titleColor,
+ mainAlignment: textAlignment,
+ maxMainAxis: width,
+ });
+ elements.push(...titleText.elements);
+ textAnchor.y += titleText.dimensions.height() + titlesSpacing;
+ boundsEnd.y +=
+ titleText.dimensions.height() + (subTitle ? titlesSpacing : 0);
+ }
+
+ if (subTitle) {
+ const subTitleText = createText({
+ text: subTitle,
+ style: subTitleType,
+ anchorPoint: textAnchor,
+ color: subTitleColor,
+ mainAlignment: textAlignment,
+ maxMainAxis: width,
+ });
+ elements.push(...subTitleText.elements);
+ boundsEnd.y += subTitleText.dimensions.height();
+ }
+
+ return {
+ elements,
+ dimensions: new Rectangle(
+ boundsStart.x,
+ boundsStart.y,
+ boundsEnd.x - boundsStart.x,
+ boundsEnd.y - boundsStart.y,
+ ),
+ };
+};
+
+const createLegend = ({
+ series = [],
+ xPosition,
+ yPosition,
+ width,
+ align = "center",
+ colorSquareSize = 16,
+ gap = 16,
+ labelMargin = 8,
+ textType = "body1",
+ textColor = "grey",
+}) => {
+ if (xPosition === null || xPosition === undefined) {
+ throw new Error("Invalid xPosition");
+ }
+
+ if (width === null || width === undefined) {
+ throw new Error("Invalid width");
+ }
+
+ if (yPosition === null || yPosition === undefined) {
+ throw new Error("Invalid yPosition");
+ }
+
+ if (["left", "center", "right"].indexOf(align) === -1) {
+ throw new Error(`Invalid align: ${align}`);
+ }
+
+ const key = hashObjects({
+ series,
+ xPosition,
+ yPosition,
+ width,
+ align,
+ colorSquareSize,
+ gap,
+ textType,
+ textColor,
+ });
+
+ // figure out the dimensions of each series and map them into rows
+ const seriesDimensionsByRow = [
+ {
+ width: 0,
+ height: 0,
+ values: [],
+ },
+ ];
+ let currentRow = 0;
+ series.forEach((series) => {
+ const remainingRowWidth =
+ width -
+ seriesDimensionsByRow[currentRow].width -
+ (seriesDimensionsByRow[currentRow].values.length > 0 ? gap : 0);
+ const seriesTextDimensions = textDimensions(series.index, textType);
+ const seriesWidth =
+ colorSquareSize + labelMargin + seriesTextDimensions.width;
+
+ if (seriesWidth <= remainingRowWidth) {
+ seriesDimensionsByRow[currentRow].width +=
+ seriesWidth +
+ (seriesDimensionsByRow[currentRow].values.length > 0 ? gap : 0);
+ seriesDimensionsByRow[currentRow].height = Math.max(
+ seriesDimensionsByRow[currentRow].height,
+ seriesTextDimensions.height,
+ colorSquareSize,
+ );
+ seriesDimensionsByRow[currentRow].values.push(series);
+ } else {
+ seriesDimensionsByRow.push({
+ width: seriesWidth <= width ? seriesWidth : width,
+ height: Math.max(seriesTextDimensions.height, colorSquareSize),
+ values: [series],
+ });
+ currentRow += 1;
+ }
+ });
+
+ // now create the SVG elements by row based on alignment
+ const elements = [];
+ let currentY = yPosition;
+
+ seriesDimensionsByRow.forEach((row, rowIndex) => {
+ let rowLeftX =
+ align === "left"
+ ? xPosition
+ : align === "center"
+ ? xPosition + (width - row.width) / 2
+ : xPosition + width - row.width;
+ let rowCenterY = currentY + row.height / 2;
+
+ row.values.forEach((series, seriesIndex) => {
+ // create the SVG elements for the series: [color square - gap - text]
+
+ const squareYStart = rowCenterY - colorSquareSize / 2;
+ const colorSquare = (
+
+ );
+ elements.push(colorSquare);
+ rowLeftX += colorSquareSize + labelMargin;
+
+ // get the height of the rendered text first
+ const tmpSeriesText = createText({
+ text: series.index,
+ style: textType,
+ anchorPoint: new Point(0, 0),
+ maxMainAxis: width - rowLeftX,
+ });
+ const seriesText = createText({
+ text: series.index,
+ style: textType,
+ anchorPoint: new Point(rowLeftX, currentY),
+ color: textColor,
+ maxMainAxis: width - rowLeftX,
+ });
+
+ elements.push(...seriesText.elements);
+ rowLeftX += seriesText.dimensions.width() + gap;
+ });
+
+ currentY += row.height + labelMargin;
+ });
+
+ currentY -= labelMargin; // remove the last spacing
+
+ return {
+ elements,
+ dimensions: new Rectangle(
+ xPosition,
+ yPosition,
+ width,
+ currentY - yPosition,
+ ),
+ };
+};
+
+const createVerticalAxis = ({
+ xPosition,
+ yPosition,
+ height,
+ steps = null,
+ stepsMargin = 8,
+ format = null,
+ label = null,
+ labelType = "body1",
+ labelColor = "grey",
+ labelMargin = 8,
+}) => {
+ if (xPosition === null || xPosition === undefined) {
+ throw new Error("Invalid xPosition");
+ }
+
+ if (height === null || height === undefined) {
+ throw new Error("Invalid width");
+ }
+
+ if (yPosition === null || yPosition === undefined) {
+ throw new Error("Invalid yPosition");
+ }
+
+ const key = hashObjects({
+ xPosition,
+ yPosition,
+ height,
+ steps,
+ stepsMargin,
+ format,
+ label,
+ labelType,
+ labelColor,
+ labelMargin,
+ });
+ const elements = [];
+ const boundsStart = new Point(xPosition, yPosition);
+ const boundsEnd = new Point(xPosition, yPosition + height);
+
+ // create the label, if it exists
+ if (label) {
+ const labelText = createText({
+ text: label,
+ style: labelType,
+ anchorPoint: new Point(xPosition, yPosition + height / 2),
+ color: labelColor,
+ mainAlignment: "middle",
+ maxMainAxis: height,
+ rotation: 270,
+ });
+ elements.push(...labelText.elements);
+ boundsEnd.x += labelText.dimensions.width() + labelMargin;
+ elements.push((
+
+ ))
+ }
+
+ // create the steps, if they exist
+ if (steps) {
+ // calculate anchors for each step
+ // index 0 is top aligned, last index is bottom aligned, all others are equally spaced and centered
+ const stepsSpacing = height / (steps.length - 1);
+ const stepsX = xPosition + stepsMargin;
+
+ steps.forEach((step, index) => {
+ let anchorPoint;
+ let secondaryAlignment;
+
+ if (index === 0) {
+ anchorPoint = new Point(stepsX, yPosition + height);
+ secondaryAlignment = "end";
+ } else if (index === steps.length - 1) {
+ anchorPoint = new Point(stepsX, yPosition);
+ secondaryAlignment = "start";
+ } else {
+ anchorPoint = new Point(stepsX, (yPosition + height) - stepsSpacing * index);
+ secondaryAlignment = "middle";
+ }
+
+ const stepText = createText({
+ text: format ? stringFormat(step, format) : step,
+ style: labelType,
+ anchorPoint,
+ color: labelColor,
+ mainAlignment: "start",
+ secondaryAlignment,
+ maxMainAxis: stepsSpacing / 2,
+ });
+ elements.push(...stepText.elements);
+
+ const stepRight = stepText.dimensions.x + stepText.dimensions.width();
+ boundsEnd.x = Math.max(boundsEnd.x, stepRight);
+ });
+ }
+
+ const debugRect = (
+
+ );
+ elements.push(debugRect);
+
+ return {
+ elements,
+ dimensions: new Rectangle(
+ boundsStart.x,
+ boundsStart.y,
+ boundsEnd.x - boundsStart.x,
+ boundsEnd.y - boundsStart.y,
+ ),
+ };
+
+ // // determine all dimensions needed
+ // let labelBounds = new Rectangle(0, 0, 0, height);
+ // let stepsContainerBounds = new Rectangle(0, 0, 0, height);
+ // const stepBounds = [];
+ //
+ // if (label) {
+ // const { bounds } = createText({
+ // text: label,
+ // style: labelType,
+ // anchorPoint: new Point(0, 0),
+ // color: labelColor,
+ // maxMainAxis: height,
+ // orientation: "vertical",
+ // mainAlignment: "middle",
+ // });
+ // labelBounds = new Rectangle(0, 0, bounds.width, height);
+ // }
+ //
+ // if (steps) {
+ // const maxStepWidth = steps
+ // .map((step) => {
+ // const { bounds } = createText({
+ // text: format ? stringFormat(step, format) : step,
+ // style: labelType,
+ // anchorPoint: new Point(0, 0),
+ // color: labelColor,
+ // });
+ // stepBounds.push(bounds);
+ //
+ // return bounds.width;
+ // })
+ // .reduce((a, b) => Math.max(a, b), 0);
+ // stepsContainerBounds = new Rectangle(0, 0, maxStepWidth, height);
+ // }
+ //
+ // const elements = [];
+ // const totalStepsHeight = stepBounds
+ // .map((bounds) => bounds.height)
+ // .reduce((a, b) => a + b, 0);
+ // const middleStepsHeight =
+ // totalStepsHeight -
+ // stepBounds[0].height -
+ // stepBounds[stepBounds.length - 1].height;
+ // const middleStepsPadding = (height - totalStepsHeight) / (steps.length - 1);
+ // let currentX = anchorPoint.x;
+ //
+ // if (position === "left") {
+ // // create the label, if it exists
+ // if (label) {
+ // const { svgText, height } = createText({
+ // text: label,
+ // style: labelType,
+ // anchorPoint: new Point(currentX, anchorPoint.y),
+ // color: labelColor,
+ // maxMainAxis: height,
+ // orientation: "vertical",
+ // });
+ // elements.push(svgText);
+ // currentX += labelBounds.width + labelPadding;
+ // }
+ //
+ // // create the steps, if they exist
+ // let currentY = anchorPoint.y;
+ //
+ // if (steps) {
+ // for (let i = 0; i < steps.length; i++) {
+ // const { svgText, height } = createText({
+ // text: format ? stringFormat(steps[i], format) : steps[i],
+ // style: labelType,
+ // anchorPoint: new Point(currentX, currentY),
+ // color: labelColor,
+ // });
+ // elements.push(svgText);
+ // currentY += height + (i === 0 ? middleStepsPadding : 0);
+ // }
+ //
+ // currentX += stepsContainerBounds.width + stepsPadding;
+ // }
+ // } else if (position === "right") {
+ // let currentY = anchorPoint.y;
+ //
+ // // on the right side, create the steps first
+ // if (steps) {
+ // currentX += stepsPadding;
+ //
+ // for (let i = 0; i < steps.length; i++) {
+ // const { svgText, height } = createText({
+ // text: format ? stringFormat(steps[i], format) : steps[i],
+ // style: labelType,
+ // anchorPoint: new Point(currentX, currentY),
+ // color: labelColor,
+ // });
+ // elements.push(svgText);
+ // currentY += height + (i === 0 ? middleStepsPadding : 0);
+ // }
+ // }
+ //
+ // // create the label, if it exists
+ // if (label) {
+ // currentX += labelPadding;
+ //
+ // const { svgText, height } = createText({
+ // text: label,
+ // style: labelType,
+ // anchorPoint: new Point(currentX, anchorPoint.y),
+ // color: labelColor,
+ // maxMainAxis: height,
+ // orientation: "vertical_180",
+ // });
+ // elements.push(svgText);
+ // }
+ // }
+ //
+ // return {
+ // elements,
+ // dimensions: new Rectangle(
+ // anchorPoint.x,
+ // anchorPoint.y,
+ // currentX - anchorPoint.x,
+ // height,
+ // ),
+ // };
+};
+
+const createHorizontalAxis = ({
+ xPosition,
+ yPosition,
+ width,
+ steps = null,
+ stepsMargin = 8,
+ format = null,
+ label = null,
+ labelType = "body1",
+ labelColor = "grey",
+ labelMargin = 8,
+}) => {
+ if (xPosition === null || xPosition === undefined) {
+ throw new Error("Invalid xPosition");
+ }
+
+ if (width === null || width === undefined) {
+ throw new Error("Invalid width");
+ }
+
+ if (yPosition === null || yPosition === undefined) {
+ throw new Error("Invalid yPosition");
+ }
+
+ const key = hashObjects({
+ xPosition,
+ yPosition,
+ width,
+ steps,
+ stepsMargin,
+ format,
+ label,
+ labelType,
+ labelColor,
+ labelMargin,
+ });
+ const elements = [];
+ const boundsStart = new Point(xPosition, yPosition);
+ const boundsEnd = new Point(xPosition + width, yPosition);
+
+ // create the steps, if they exist
+ if (steps) {
+ // calculate anchors for each step
+ // index 0 is left aligned, last index is right aligned, all others are equally spaced and centered
+ const stepsSpacing = width / (steps.length - 1);
+ const stepsY = yPosition + stepsMargin;
+
+ steps.forEach((step, index) => {
+ let anchorPoint;
+ let mainAlignment;
+
+ if (index === 0) {
+ anchorPoint = new Point(xPosition, stepsY);
+ mainAlignment = "start";
+ } else if (index === steps.length - 1) {
+ anchorPoint = new Point(xPosition + width, stepsY);
+ mainAlignment = "end";
+ } else {
+ anchorPoint = new Point(xPosition + stepsSpacing * index, stepsY);
+ mainAlignment = "middle";
+ }
+
+ const stepText = createText({
+ text: format ? stringFormat(step, format) : step,
+ style: labelType,
+ anchorPoint,
+ color: labelColor,
+ mainAlignment,
+ maxMainAxis: stepsSpacing / 2,
+ });
+ elements.push(...stepText.elements);
+
+ const stepBottom = stepText.dimensions.y + stepText.dimensions.height();
+ boundsEnd.y = Math.max(boundsEnd.y, stepBottom);
+ });
+ }
+
+ // create the label if it exists
+ if (label) {
+ const labelText = createText({
+ text: label,
+ style: labelType,
+ anchorPoint: new Point(xPosition + width / 2, boundsEnd.y + labelMargin),
+ color: labelColor,
+ mainAlignment: "middle",
+ maxMainAxis: width,
+ });
+ elements.push(...labelText.elements);
+ boundsEnd.y += labelText.dimensions.height() + labelMargin;
+ }
+
+ return {
+ elements,
+ dimensions: new Rectangle(
+ boundsStart.x,
+ boundsStart.y,
+ boundsEnd.x - boundsStart.x,
+ boundsEnd.y - boundsStart.y,
+ ),
+ };
+};
+
+export {
+ createBackground,
+ createGraphBackground,
+ createHeading,
+ createLegend,
+ createVerticalAxis,
+ createHorizontalAxis,
+};
diff --git a/src/components/graphs/line/index.jsx b/src/components/graphs/line/index.jsx
new file mode 100644
index 00000000000..c39d3b77c62
--- /dev/null
+++ b/src/components/graphs/line/index.jsx
@@ -0,0 +1,500 @@
+import React from "react";
+
+import { Point, Line, Triangle, Polygon, Rectangle } from "../vector";
+import { pointsToPathD, lineToPathD, createText, stringFormat } from "../svg";
+import {
+ createHeading,
+ createLegend,
+ createVerticalAxis,
+ createHorizontalAxis,
+ createBackground,
+ createGraphBackground,
+} from "../graphs.svg";
+import { extractData } from "../data";
+import theme from "../theme";
+import { splitText } from "../utilities";
+
+const createLineGraph = ({
+ series,
+ verticalAxisBounds,
+ horizontalAxisBounds,
+ anchorPoint,
+ width,
+ height,
+ lineStrokeWidth = 4,
+ pointRadius = 8,
+}) => {
+ const bounds = new Rectangle(anchorPoint.x, anchorPoint.y, width, height);
+ const elements = [];
+
+ // convert each series data into markers for each point and lines between each point
+ series.forEach((series, seriesIndex) => {
+ const color = series.color;
+ const lines = [];
+ const markers = [];
+ let previousPoint = null;
+
+ series.values.forEach(({ value, label }, index) => {
+ const percentX =
+ (value - horizontalAxisBounds.min) /
+ (horizontalAxisBounds.max - horizontalAxisBounds.min);
+ const percentY =
+ (value - verticalAxisBounds.min) /
+ (verticalAxisBounds.max - verticalAxisBounds.min);
+ const point = new Point(
+ anchorPoint.x + width * percentX,
+ anchorPoint.y + height * percentY,
+ );
+
+ if (previousPoint && lineStrokeWidth && lineStrokeWidth > 0) {
+ lines.push(
+
,
+ );
+ }
+
+ if (pointRadius && pointRadius > 0) {
+ markers.push(
+
,
+ );
+ }
+ });
+
+ elements.push(...lines);
+ elements.push(...markers);
+ });
+
+ return {
+ elements,
+ dimensions: bounds,
+ };
+};
+
+const NeuralMagicLineChart = ({
+ // data
+ children,
+ file,
+ data,
+ testDataType = null,
+
+ // general graph properties
+ width = 560,
+ height = 480,
+ chartStyle = "rectangular",
+ chartColorScheme = "light",
+ textScale = "normal",
+ seriesColorShift = 0,
+ markersSize = 8,
+ linesSize = 4,
+
+ // heading properties
+ alignHeading = "left",
+ title = null,
+ subTitle = null,
+
+ // legend properties
+ enableLegend = true,
+ legendAlign = "center",
+
+ // x axis properties
+ showXAxis = true,
+ xAxisLabel = "Test X Axis Label",
+ xAxisValues = null,
+ xAxisValuesTotalSteps = 4,
+ xAxisValuesFormat = "#.#",
+
+ // y axis properties
+ showYAxis = true,
+ yAxisLabel = "Test Y Axis Label",
+ yAxisValues = null,
+ yAxisValuesTotalSteps = 4,
+ yAxisValuesFormat = "#.#",
+}) => {
+ // get the data
+ const extracted = extractData({
+ data,
+ children,
+ file,
+ testDataType,
+ chartType: "line",
+ indexColors: theme.colors.data.series,
+ colorShift: seriesColorShift,
+ });
+ if (!xAxisValues || xAxisValues.length === 0 || xAxisValues.length < 3) {
+ let min =
+ xAxisValues && xAxisValues.length > 0
+ ? xAxisValues[0]
+ : Math.min(extracted.data.map((item) => item.label));
+ let max =
+ xAxisValues && xAxisValues.length > 1
+ ? xAxisValues[1]
+ : Math.max(extracted.data.map((item) => item.label));
+ let distance = max - min;
+ min = min - distance * 0.1;
+ max = max + distance * 0.1;
+ const stepDistance = (max - min) / xAxisValuesTotalSteps;
+ xAxisValues = [];
+ for (let i = 0; i <= xAxisValuesTotalSteps; i++) {
+ xAxisValues.push(min + stepDistance * i);
+ }
+ }
+ if (!yAxisValues || yAxisValues.length === 0 || yAxisValues.length < 3) {
+ let min =
+ yAxisValues && yAxisValues.length > 0
+ ? yAxisValues[0]
+ : Math.min(extracted.data.map((item) => item.value));
+ let max =
+ yAxisValues && yAxisValues.length > 1
+ ? yAxisValues[1]
+ : Math.max(extracted.data.map((item) => item.value));
+ let distance = max - min;
+ min = min - distance * 0.1;
+ max = max + distance * 0.1;
+ const stepDistance = (max - min) / yAxisValuesTotalSteps;
+ yAxisValues = [];
+ for (let i = 0; i <= yAxisValuesTotalSteps; i++) {
+ yAxisValues.push(min + stepDistance * i);
+ }
+ }
+
+ // start creating the graph
+ const layeredElements = {
+ backgrounds: [],
+ headings: [],
+ legends: [],
+ axis: [],
+ graphs: [],
+ };
+ const currentPoint = new Point(
+ theme.styles.spacing.outerPadding,
+ theme.styles.spacing.outerPadding,
+ );
+
+ // create the heading first to enable background creation for the pull tab setup
+ const heading = createHeading({
+ xPosition: currentPoint.x,
+ width: width - 2 * theme.styles.spacing.outerPadding,
+ yPosition: currentPoint.y,
+ align: alignHeading,
+ title,
+ titleType: theme.styles.font.sizes[textScale].title,
+ titleColor: theme.functions.chartSchemeColor(
+ chartColorScheme,
+ "textPrimary",
+ ),
+ titlesSpacing: theme.styles.spacing.titleSubTitleMargin,
+ subTitle,
+ subTitleType: theme.styles.font.sizes[textScale].subTitle,
+ subTitleColor: theme.functions.chartSchemeColor(
+ chartColorScheme,
+ "textSecondary",
+ ),
+ });
+ layeredElements.headings.push(...heading.elements);
+ currentPoint.y = heading.dimensions.y + heading.dimensions.height();
+
+ // create the background next (needs the heading height) to figure out where the graph will fit
+ const background = createBackground({
+ width,
+ height,
+ bottomHeading: currentPoint.y,
+ headingMargin: theme.styles.spacing.headingMargin,
+ color: theme.functions.chartSchemeColor(chartColorScheme, "background"),
+ borderColor: theme.functions.chartSchemeColor(chartColorScheme, "border"),
+ borderWidth: 1,
+ stylePulltab: chartStyle === "pulltab",
+ });
+ layeredElements.backgrounds.push(...background.elements);
+ currentPoint.y = background.graphTop;
+
+ // start creating the graph
+
+ // create the legend first, legend is always above the graph if included
+ let legend = null;
+
+ if (enableLegend) {
+ legend = createLegend({
+ series: extracted.indices,
+ xPosition: currentPoint.x,
+ yPosition: currentPoint.y,
+ width: width - 2 * theme.styles.spacing.outerPadding,
+ align: "center",
+ gap: 16,
+ textType: theme.styles.font.sizes[textScale].axisLabels,
+ textColor:
+ chartColorScheme === "light" || chartColorScheme === "grey"
+ ? theme.colors.font.colors.light.primary
+ : theme.colors.font.colors.dark.primary,
+ });
+ layeredElements.legends.push(...legend.elements);
+ currentPoint.y = legend.dimensions.y + legend.dimensions.height();
+ }
+
+ // determine the height of the horizontal axis to subtract from vertical axis and graph to fit everything
+ let horizontalAxisProjectedHeight = 0;
+ if (showXAxis) {
+ const tmpHorizontal = createHorizontalAxis({
+ xPosition: currentPoint.x,
+ yPosition: currentPoint.y,
+ width: width - theme.styles.spacing.outerPadding * 2,
+ steps: xAxisValues,
+ stepsMargin: 8,
+ format: xAxisValuesFormat,
+ label: xAxisLabel,
+ labelType: theme.styles.font.sizes[textScale].axisLabels,
+ labelColor:
+ chartColorScheme === "light" || chartColorScheme === "grey"
+ ? theme.colors.font.colors.light.secondary
+ : theme.colors.font.colors.dark.secondary,
+ labelMargin: 8,
+ });
+ horizontalAxisProjectedHeight = tmpHorizontal.dimensions.height();
+ }
+
+ const graphHeight =
+ height -
+ currentPoint.y -
+ theme.styles.spacing.outerPadding -
+ horizontalAxisProjectedHeight;
+
+ // create the vertical axis
+ if (showYAxis) {
+ const verticalAxis = createVerticalAxis({
+ xPosition: currentPoint.x,
+ yPosition: currentPoint.y,
+ height: graphHeight,
+ steps: yAxisValues,
+ stepsMargin: 8,
+ format: yAxisValuesFormat,
+ label: yAxisLabel,
+ labelType: theme.styles.font.sizes[textScale].axisLabels,
+ labelColor:
+ chartColorScheme === "light" || chartColorScheme === "grey"
+ ? theme.colors.font.colors.light.secondary
+ : theme.colors.font.colors.dark.secondary,
+ labelMargin: 8,
+ });
+ layeredElements.axis.push(...verticalAxis.elements);
+ currentPoint.x += verticalAxis.dimensions.width();
+ }
+
+ return (
+
+ {layeredElements.backgrounds}
+ {layeredElements.headings}
+ {layeredElements.legends}
+ {layeredElements.axis}
+ {layeredElements.graphs}
+
+ );
+};
+
+export default NeuralMagicLineChart;
+
+const func = () => {
+ // // create the legend
+ // let legend = null;
+ //
+ // if (enableLegend) {
+ // legend = createLegend({
+ // series,
+ // anchorPoint: currentPoint,
+ // maxWidth: width - padding * 2,
+ // align: legendAlign,
+ // colorSquareSize: markersSize,
+ // gap: 8,
+ // textType: textStyleMappings[textScale].axisLabels,
+ // textColor:
+ // chartColorScheme === "light" || chartColorScheme === "grey"
+ // ? colors.lightTextPrimary
+ // : colors.darkTextPrimary,
+ // });
+ //
+ // elements.legends.push(...legend.elements);
+ // currentPoint.y += legend.dimensions.height;
+ // }
+ //
+ // if (!yAxisValues) {
+ // const min = Math.min(
+ // ...series.map((series) =>
+ // Math.min(...series.values.map((value) => value.value)),
+ // ),
+ // );
+ // const max = Math.max(
+ // ...series.map((series) =>
+ // Math.max(...series.values.map((value) => value.value)),
+ // ),
+ // );
+ // const step = (max - min) / yAxisValuesTotalSteps;
+ // yAxisValues = Array.from(
+ // { length: yAxisValuesTotalSteps + 1 },
+ // (_, i) => min + step * i,
+ // );
+ // } else if (yAxisValues.length === 2) {
+ // const min = yAxisValues[0];
+ // const max = yAxisValues[1];
+ // const step = (max - min) / yAxisValuesTotalSteps;
+ // yAxisValues = Array.from(
+ // { length: yAxisValuesTotalSteps + 1 },
+ // (_, i) => min + step * i,
+ // );
+ // }
+ //
+ // if (!xAxisValues) {
+ // const min = Math.min(
+ // ...series.map((series) =>
+ // Math.min(...series.values.map((value) => value.label)),
+ // ),
+ // );
+ // const max = Math.max(
+ // ...series.map((series) =>
+ // Math.max(...series.values.map((value) => value.label)),
+ // ),
+ // );
+ // const step = (max - min) / xAxisValuesTotalSteps;
+ // xAxisValues = Array.from(
+ // { length: xAxisValuesTotalSteps + 1 },
+ // (_, i) => min + step * i,
+ // );
+ // } else if (xAxisValues.length === 2) {
+ // const min = xAxisValues[0];
+ // const max = xAxisValues[1];
+ // const step = (max - min) / xAxisValuesTotalSteps;
+ // xAxisValues = Array.from(
+ // { length: xAxisValuesTotalSteps + 1 },
+ // (_, i) => min + step * i,
+ // );
+ // }
+ //
+ // // check the height of the horizontal axis to subtract from vertical axis and graph to fit everything
+ // let horizontalAxisProjectedHeight = 0;
+ //
+ // if (showXAxis) {
+ // const tmpHorizontal = createHorizontalAxis({
+ // anchorPoint: currentPoint,
+ // width: width - padding * 2,
+ // steps: xAxisValues,
+ // stepsPadding: 8,
+ // format: xAxisValuesFormat,
+ // position: "bottom",
+ // label: xAxisLabel,
+ // labelType: textStyleMappings[textScale].axisLabels,
+ // labelColor:
+ // chartColorScheme === "light" || chartColorScheme === "grey"
+ // ? colors.lightTextSecondary
+ // : colors.darkTextSecondary,
+ // labelPadding: 8,
+ // });
+ // horizontalAxisProjectedHeight = tmpHorizontal.dimensions.height;
+ // }
+ //
+ // // create the vertical axis
+ // if (showYAxis) {
+ // const verticalAxis = createVerticalAxis({
+ // anchorPoint: currentPoint,
+ // height: height - currentPoint.y - padding - horizontalAxisProjectedHeight,
+ // steps: yAxisValues,
+ // stepsPadding: 8,
+ // format: yAxisValuesFormat,
+ // position: "left",
+ // label: yAxisLabel,
+ // labelType: textStyleMappings[textScale].axisLabels,
+ // labelColor:
+ // chartColorScheme === "light" || chartColorScheme === "grey"
+ // ? colors.lightTextSecondary
+ // : colors.darkTextSecondary,
+ // labelPadding: 8,
+ // });
+ // elements.axis.push(...verticalAxis.elements);
+ // currentPoint.x += verticalAxis.dimensions.width;
+ // }
+ //
+ // // create the graph
+ // const graph = createLineGraph({
+ // series,
+ // verticalAxisBounds: {
+ // min: yAxisValues[0],
+ // max: yAxisValues[yAxisValues.length - 1],
+ // },
+ // horizontalAxisBounds: {
+ // min: xAxisValues[0],
+ // max: xAxisValues[xAxisValues.length - 1],
+ // },
+ // anchorPoint: currentPoint,
+ // width: width - currentPoint.x - padding,
+ // height: height - currentPoint.y - padding - horizontalAxisProjectedHeight,
+ // lineStrokeWidth: linesSize,
+ // pointRadius: markersSize,
+ // });
+ // elements.graphs.push(...graph.elements);
+ // currentPoint.y += graph.dimensions.height;
+ //
+ // // create the horizontal axis
+ // if (showXAxis) {
+ // const horizontalAxis = createHorizontalAxis({
+ // anchorPoint: currentPoint,
+ // width: width - currentPoint.x - padding,
+ // steps: xAxisValues,
+ // stepsPadding: 8,
+ // format: xAxisValuesFormat,
+ // position: "bottom",
+ // label: xAxisLabel,
+ // labelType: textStyleMappings[textScale].axisLabels,
+ // labelColor:
+ // chartColorScheme === "light" || chartColorScheme === "grey"
+ // ? colors.lightTextSecondary
+ // : colors.darkTextSecondary,
+ // labelPadding: 8,
+ // });
+ // elements.axis.push(...horizontalAxis.elements);
+ // currentPoint.y += horizontalAxis.dimensions.height;
+ // }
+ //
+ // // create the background
+ // const background = createBackground({
+ // width,
+ // height,
+ // headingHeight: heading.dimensions.height,
+ // cornerRadius: 16,
+ // color:
+ // chartColorScheme === "light"
+ // ? colors.lightBackground
+ // : chartColorScheme === "grey"
+ // ? colors.greyBackground
+ // : colors.darkBackground,
+ // borderColor:
+ // chartColorScheme === "light"
+ // ? colors.lightBorder
+ // : chartColorScheme === "grey"
+ // ? colors.greyBorder
+ // : colors.darkBorder,
+ // borderWidth: 1,
+ // stylePulltab: chartStyle === "pulltab",
+ // pullTabGap: 16,
+ // pullTabInset: 48,
+ // });
+ // elements.backgrounds.push(background);
+ // const graphBackground = createGraphBackground({
+ // anchorPoint: graph.dimensions.points[0],
+ // width: graph.dimensions.width(),
+ // height: graph.dimensions.height(),
+ // color:
+ // chartColorScheme === "light"
+ // ? colors.lightGraphBackground
+ // : chartColorScheme === "grey"
+ // ? colors.greyGraphBackground
+ // : colors.darkGraphBackground,
+ // cornerRadius: 16,
+ // borderColor:
+ // chartColorScheme === "light"
+ // ? colors.lightBorder
+ // : chartColorScheme === "grey"
+ // ? colors.greyBorder
+ // : colors.darkBorder,
+ // borderWidth: 1,
+ // verticalAxisSide: showYAxis ? "start" : "",
+ // horizontalAxisSide: showXAxis ? "end" : "",
+ // });
+};
diff --git a/src/components/graphs/neuralnet/index.jsx b/src/components/graphs/neuralnet/index.jsx
new file mode 100644
index 00000000000..e93ec7802e8
--- /dev/null
+++ b/src/components/graphs/neuralnet/index.jsx
@@ -0,0 +1,263 @@
+import React from "react";
+import seedrandom from "seedrandom";
+import { Line, Point } from "../vector";
+import { lineToPathD } from "../svg";
+import theme from "../theme";
+
+const sparseWeightsEmulator = (layers, sparsity, layerVariance, seed) => {
+ console.log("sparseWeightsEmulator");
+ const random = seedrandom(seed);
+ const layersWeights = [];
+ console.log(layers);
+
+ for (let layerIndex = 0; layerIndex < layers.length - 1; layerIndex++) {
+ layersWeights.push([]);
+ const sourceActivations = layers[layerIndex];
+ const targetActivations = layers[layerIndex + 1];
+ const totalWeights = sourceActivations * targetActivations;
+ const minDenseWeights = (1 - (sparsity + layerVariance)) * totalWeights;
+
+ // create random weight values between 0 and 1 while setting the number of weights needed for minDensity to 2
+ const weightValues = [];
+ let denseCount = 0;
+
+ for (let i = 0; i < totalWeights; i++) {
+ if (denseCount < minDenseWeights) {
+ weightValues.push(2);
+ denseCount++;
+ } else {
+ weightValues.push(random());
+ }
+ }
+
+ // assign random weights from the list to the connections
+ for (let sourceIndex = 0; sourceIndex < sourceActivations; sourceIndex++) {
+ for (
+ let targetIndex = 0;
+ targetIndex < targetActivations;
+ targetIndex++
+ ) {
+ const randomIndex = Math.floor(random() * weightValues.length);
+ const weight = weightValues.splice(randomIndex, 1)[0];
+ layersWeights[layerIndex].push(weight);
+ }
+ }
+ }
+
+ // now set the weights to sparse or dense based on their values while hitting the global sparsity target
+ const weightValues = layersWeights.flat();
+ weightValues.sort();
+ const sparsityIndex = Math.floor(weightValues.length * sparsity);
+ const denseThreshold = weightValues[sparsityIndex];
+
+ for (let layerIndex = 0; layerIndex < layersWeights.length; layerIndex++) {
+ for (
+ let weightIndex = 0;
+ weightIndex < layersWeights[layerIndex].length;
+ weightIndex++
+ ) {
+ layersWeights[layerIndex][weightIndex] =
+ layersWeights[layerIndex][weightIndex] < denseThreshold;
+ }
+ }
+
+ return layersWeights;
+};
+
+const NeuralMagicNeuralNet = ({
+ layers = [3, 4, 4, 2],
+ activationSize = 96,
+ weightSize = 20,
+ activationSpacing = 64,
+ activationStrokeWidth = 4,
+ layerSpacing = null,
+ colorIndex = 3,
+ sparsity = 0.7,
+ sparsityRandomSeed = 9,
+ weightCompression = 4,
+ activationCompression = 2,
+}) => {
+ // if (!activationSpacing) {
+ // activationSpacing = activationSize * 0.5;
+ // }
+ //
+ // if (!layerSpacing) {
+ // layerSpacing = activationSpacing;
+ // }
+ //
+ // const maxLayerSize = Math.max(...layers);
+ // const layerCount = layers.length;
+ // const activationRadius = activationSize / 2;
+ // const quantizedActivationRadius = activationRadius / activationCompression;
+ // const weightWidth = weightSize;
+ // const quantizedWeightWidth = weightSize / weightCompression;
+ //
+ // const totalHeight =
+ // maxLayerSize * activationSize +
+ // (maxLayerSize - 1) * activationSpacing +
+ // 2 * activationStrokeWidth;
+ // const totalWidth =
+ // layerCount * activationSize +
+ // (layerCount - 1) * layerSpacing +
+ // 2 * activationStrokeWidth;
+ //
+ // const layersActivations = [];
+ //
+ // for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) {
+ // const activations = [];
+ // const layerSize = layers[layerIndex];
+ // const layerWidth = activationSize + 2 * activationStrokeWidth;
+ // const layerHeight =
+ // layerSize * activationSize + (layerSize - 1) * activationSpacing;
+ // const layerX =
+ // layerIndex * (activationSize + layerSpacing) + activationStrokeWidth;
+ // const layerY = (totalHeight - layerHeight) / 2;
+ //
+ // for (let nodeIndex = 0; nodeIndex < layerSize; nodeIndex++) {
+ // const centerX = layerX + activationRadius;
+ // const centerY =
+ // layerY +
+ // activationRadius +
+ // nodeIndex * (activationSize + activationSpacing);
+ // activations.push({
+ // base: new Point(centerX, centerY),
+ // quantized: activationCompression > 1,
+ // });
+ // }
+ //
+ // layersActivations.push(activations);
+ // }
+ //
+ // const activationsList = layersActivations.flat();
+ // const weights = [];
+ // const sparseWeights = sparseWeightsEmulator(
+ // layers,
+ // sparsity,
+ // 0,
+ // sparsityRandomSeed,
+ // );
+ //
+ // for (let layerIndex = 0; layerIndex < layers.length - 1; layerIndex++) {
+ // const sourceLayer = layersActivations[layerIndex];
+ // const targetLayer = layersActivations[layerIndex + 1];
+ //
+ // for (
+ // let sourceNodeIndex = 0;
+ // sourceNodeIndex < sourceLayer.length;
+ // sourceNodeIndex++
+ // ) {
+ // const source = sourceLayer[sourceNodeIndex].base;
+ //
+ // for (
+ // let targetNodeIndex = 0;
+ // targetNodeIndex < targetLayer.length;
+ // targetNodeIndex++
+ // ) {
+ // const target = targetLayer[targetNodeIndex].base;
+ // const weight = {
+ // base: new Line(
+ // new Point(source.x, source.y),
+ // new Point(target.x, target.y),
+ // ),
+ // quantized: weightCompression > 1,
+ // sparse:
+ // sparsity > 0 &&
+ // sparseWeights[layerIndex][
+ // sourceNodeIndex * targetLayer.length + targetNodeIndex
+ // ],
+ // };
+ //
+ // weights.push(weight);
+ // }
+ // }
+ // }
+ //
+ // const weightColor = "#848990";
+ // const weightStrokeColor = colors.shadeColorHex(weightColor, -0.15);
+ // const sparseWeightColor = colors.setAlphaHex(weightColor, 0.25);
+ // const activationColor = colors.series[colorIndex % colors.series.length];
+ // const uncompressedActivationColor = colors.setAlphaHex(activationColor, 0.25);
+ // const activationStrokeColor = colors.shadeColorHex(
+ // colors.series[colorIndex % colors.series.length],
+ // -0.15,
+ // );
+ //
+ // return (
+ //
+ // {weights.map((weight, index) => {
+ // // base weights
+ // return (
+ //
+ // );
+ // })}
+ // {weights.map((weight, index) => {
+ // // quantized weights
+ // if (weight.sparse || !weight.quantized) {
+ // return null;
+ // }
+ //
+ // return (
+ //
+ // );
+ // })}
+ // {activationsList.map((activation, layerIndex) => {
+ // return (
+ //
+ // );
+ // })}
+ // {activationsList.map((activation, layerIndex) => {
+ // // quantized activations
+ // if (!activation.quantized) {
+ // return null;
+ // }
+ //
+ // return (
+ //
+ // );
+ // })}
+ //
+ // );
+};
+
+export default NeuralMagicNeuralNet;
diff --git a/src/components/graphs/svg.jsx b/src/components/graphs/svg.jsx
new file mode 100644
index 00000000000..2bee13cee97
--- /dev/null
+++ b/src/components/graphs/svg.jsx
@@ -0,0 +1,279 @@
+import { Point, Line, Rectangle } from "./vector";
+import theme from "./theme";
+import { atan2 } from "mathjs";
+import { hashObjects, splitText } from "./utilities";
+
+function pointsToPathD({ points, cornerRadius = 0, closePath = true }) {
+ const cornerRadii =
+ typeof cornerRadius === "number"
+ ? new Array(points.length).fill(cornerRadius)
+ : cornerRadius;
+
+ // First map the points to vertices taking into account any corner radius
+ // veretx format is {start: Point, control: Point, end: Point, hasCorner: boolean}
+ const vertices = [];
+ points.forEach((point, index) => {
+ const prevPoint = points[index - 1] || points[points.length - 1];
+ const nextPoint = points[(index + 1) % points.length];
+ const currentCornerRadius = cornerRadii[index];
+
+ if (!currentCornerRadius || currentCornerRadius < 1) {
+ vertices.push({
+ start: point,
+ control: point,
+ end: point,
+ hasCorner: false,
+ });
+ } else {
+ const startLine = new Line(prevPoint, point);
+ const endLine = new Line(point, nextPoint);
+
+ vertices.push({
+ start: startLine.pointAt(
+ (startLine.length() - currentCornerRadius) / startLine.length(),
+ ),
+ control: point,
+ end: endLine.pointAt(currentCornerRadius / endLine.length()),
+ hasCorner: true,
+ });
+ }
+ });
+ vertices.push(vertices[0]);
+
+ // Now map the vertices to SVG path d attribute format
+ const d = [];
+ vertices.forEach((vertex, index) => {
+ if (index === 0) {
+ d.push(`M ${vertex.end.x},${vertex.end.y}`);
+ } else if (!vertex.hasCorner) {
+ d.push(`L ${vertex.control.x},${vertex.control.y}`);
+ } else {
+ d.push(`L ${vertex.start.x},${vertex.start.y}`);
+ d.push(
+ `Q ${vertex.control.x},${vertex.control.y} ${vertex.end.x},${vertex.end.y}`,
+ );
+ }
+ });
+
+ if (closePath) {
+ d.push("Z");
+ }
+
+ return d.join(" ");
+}
+
+function lineToPathD(line, thickness, closePath = true) {
+ const offset = thickness / 2;
+ let angle =
+ atan2(line.end.y - line.start.y, line.end.x - line.start.x) + Math.PI / 2;
+
+ const offsetX = offset * Math.cos(angle);
+ const offsetY = offset * Math.sin(angle);
+
+ const points = [
+ new Point(line.start.x - offsetX, line.start.y - offsetY),
+ new Point(line.start.x + offsetX, line.start.y + offsetY),
+ new Point(line.end.x + offsetX, line.end.y + offsetY),
+ new Point(line.end.x - offsetX, line.end.y - offsetY),
+ new Point(line.start.x - offsetX, line.start.y - offsetY),
+ ];
+
+ let d = "";
+
+ points.forEach((point, index) => {
+ if (index === 0) {
+ d += `M ${point.x},${point.y}`;
+ } else {
+ d += ` L ${point.x},${point.y}`;
+ }
+ });
+
+ if (closePath) {
+ d += " Z";
+ }
+
+ return d;
+}
+
+const validateTextInputs = ({
+ text,
+ style,
+ anchorPoint,
+ mainAlignment,
+ secondaryAlignment,
+}) => {
+ if (theme.styles.font.properties[style] === undefined) {
+ throw new Error(`Invalid style: ${style}`);
+ }
+
+ if (["start", "middle", "end"].indexOf(mainAlignment) === -1) {
+ throw new Error(`Invalid mainAlignment: ${mainAlignment}`);
+ }
+
+ if (["start", "middle", "end"].indexOf(secondaryAlignment) === -1) {
+ throw new Error(`Invalid secondaryAlignment: ${secondaryAlignment}`);
+ }
+
+ if (text === null || text === undefined || text === "") {
+ return {
+ elements: null,
+ dimensions: new Rectangle(anchorPoint.x, anchorPoint.y, 0, 0),
+ };
+ }
+
+ return null;
+};
+
+const createText = ({
+ text,
+ style,
+ anchorPoint,
+ color = "black",
+ mainAlignment = "start",
+ secondaryAlignment = "start",
+ maxMainAxis = null,
+ lineSpacing = 0.1,
+ rotation = 0,
+}) => {
+ const nullResponse = validateTextInputs({
+ text,
+ style,
+ anchorPoint,
+ mainAlignment,
+ secondaryAlignment,
+ });
+
+ if (nullResponse !== null) {
+ return nullResponse;
+ }
+
+ const key = hashObjects([
+ text,
+ style,
+ color,
+ mainAlignment,
+ maxMainAxis,
+ lineSpacing,
+ ]);
+
+ // Split text into lines and determine dimensions
+ const { lines, dimensions } = splitText(text, maxMainAxis, style);
+ let maxLineHeight = Math.max(...dimensions.map((dim) => dim.height));
+ let lineDeltaY = maxLineHeight * lineSpacing + maxLineHeight;
+ let maxLineWidth = Math.max(...dimensions.map((dim) => dim.width));
+ let totalHeight = lineDeltaY * (lines.length - 1) + maxLineHeight;
+
+ let textAnchorX;
+ let textAnchorY;
+ let boundAnchorX;
+ let boundAnchorY;
+
+ if (mainAlignment === "start") {
+ textAnchorX = anchorPoint.x;
+ boundAnchorX = anchorPoint.x;
+ } else if (mainAlignment === "middle") {
+ textAnchorX = anchorPoint.x;
+ boundAnchorX = anchorPoint.x - maxLineWidth / 2;
+ } else if (mainAlignment === "end") {
+ textAnchorX = anchorPoint.x;
+ boundAnchorX = anchorPoint.x - maxLineWidth;
+ }
+
+ if (secondaryAlignment === "start") {
+ textAnchorY = anchorPoint.y;
+ boundAnchorY = anchorPoint.y;
+ } else if (secondaryAlignment === "middle") {
+ textAnchorY = anchorPoint.y - totalHeight / 2;
+ boundAnchorY = anchorPoint.y - totalHeight / 2;
+ } else if (secondaryAlignment === "end") {
+ textAnchorY = anchorPoint.y - totalHeight;
+ boundAnchorY = anchorPoint.y - totalHeight;
+ }
+
+ // Rotation calculations
+ const textLineSettings = [];
+
+ if (rotation === 0) {
+ lines.forEach((line, index) => {
+ textLineSettings.push({
+ line,
+ x: textAnchorX,
+ y: textAnchorY + index * lineDeltaY,
+ textAnchor: mainAlignment,
+ alignmentBaseline: "hanging",
+ transform: "",
+ });
+ });
+ } else if (rotation === 270) {
+ maxLineWidth = lineDeltaY * (lines.length - 1) + maxLineHeight;
+ totalHeight = Math.max(...dimensions.map((dim) => dim.width));
+
+ // Reorient the text lines with the given rotation while matching alignment to the original desired anchor
+ lines.forEach((line, index) => {
+ // first find rotated center point for each line
+ const orignalX = textAnchorX;
+ const originalY = textAnchorY + index * lineDeltaY;
+ const orignalDims = dimensions[index];
+
+ // now change out all text for center anchors and alignment for easy rotation and translation
+ let originalCenterX;
+ let originalCenterY;
+
+ if (mainAlignment === "start") {
+ originalCenterX = orignalX + orignalDims.width / 2;
+ } else if (mainAlignment === "middle") {
+ originalCenterX = orignalX;
+ } else if (mainAlignment === "end") {
+ originalCenterX = orignalX - orignalDims.width / 2;
+ }
+
+ if (secondaryAlignment === "start") {
+ originalCenterY = originalY;
+ } else if (secondaryAlignment === "middle") {
+ originalCenterY = originalY + orignalDims.height / 2;
+ } else if (secondaryAlignment === "end") {
+ originalCenterY = originalY + orignalDims.height;
+ }
+
+ // convert into line settings and correct offsets
+ textLineSettings.push({
+ line,
+ x: originalCenterX,
+ y: originalCenterY + orignalDims.height / 2 + index * lineDeltaY,
+ textAnchor: "middle",
+ alignmentBaseline: "middle",
+ transform: `rotate(${rotation} ${originalCenterX} ${originalCenterY})`,
+ });
+ });
+ }
+
+ // Convert lines settings into SVG elements
+ const elements = textLineSettings.map((settings, index) => {
+ return (
+
+ {settings.line}
+
+ );
+ });
+
+ return {
+ elements,
+ dimensions: new Rectangle(
+ boundAnchorX,
+ boundAnchorY,
+ maxLineWidth,
+ totalHeight,
+ ),
+ };
+};
+
+export { pointsToPathD, lineToPathD, createText };
diff --git a/src/components/graphs/theme.jsx b/src/components/graphs/theme.jsx
new file mode 100644
index 00000000000..e1e0a89d887
--- /dev/null
+++ b/src/components/graphs/theme.jsx
@@ -0,0 +1,249 @@
+function decimalToHex(d, padding) {
+ let hex = Number(d).toString(16);
+ padding =
+ typeof padding === "undefined" || padding === null
+ ? (padding = 2)
+ : padding;
+
+ while (hex.length < padding) {
+ hex = "0" + hex;
+ }
+
+ return hex;
+}
+
+const shadeColorHex = (color, percentage) => {
+ let colorString = color.replace("#", "");
+
+ if (colorString.length === 6) {
+ colorString += "FF";
+ }
+
+ let red = parseInt(colorString.substr(0, 2), 16);
+ let green = parseInt(colorString.substr(2, 2), 16);
+ let blue = parseInt(colorString.substr(4, 2), 16);
+ const alpha = parseInt(colorString.substr(6, 2), 16);
+
+ if (percentage > 0) {
+ // lighten where 1 is full white, 0 is no change, and close to 0 is minimal change
+ red = Math.round(red + (255 - red) * percentage);
+ green = Math.round(green + (255 - green) * percentage);
+ blue = Math.round(blue + (255 - blue) * percentage);
+ } else {
+ // darken where 1 is full black, 0 is no change, and close to 0 is minimal change
+ red = Math.round(red - red * -1 * percentage);
+ green = Math.round(green - green * -1 * percentage);
+ blue = Math.round(blue - blue * -1 * percentage);
+ }
+
+ console.log(`red: ${red}, green: ${green}, blue: ${blue}, alpha: ${alpha}`);
+
+ return `#${decimalToHex(red)}${decimalToHex(green)}${decimalToHex(blue)}${decimalToHex(alpha)}`;
+};
+
+function setAlphaHex(color, opacity) {
+ let colorString = color.replace("#", "");
+
+ if (colorString.length > 6) {
+ colorString = colorString.substring(0, 6);
+ }
+
+ const alpha = Math.round(Math.min(Math.max(opacity, 0), 1) * 255);
+
+ return `#${colorString}${decimalToHex(alpha)}`;
+}
+
+const fontFamily = "Space Grotesk, sans-serif";
+const textFontProperties = {
+ h1: {
+ fontFamily,
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "96px",
+ },
+ h2: {
+ fontFamily,
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "60px",
+ },
+ h3: {
+ fontFamily: "Spezia",
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "48px",
+ },
+ h4: {
+ fontFamily,
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "32px",
+ },
+ h5: {
+ fontFamily,
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "24px",
+ },
+ h6: {
+ fontFamily,
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "20px",
+ },
+ subtitle1: {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: "600",
+ fontSize: "22px",
+ },
+ subtitle2: {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: "600",
+ fontSize: "16px",
+ },
+ body1: {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "18px",
+ },
+ body2: {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "16px",
+ },
+ caption: {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: "normal",
+ fontSize: "12px",
+ },
+};
+
+const colors = {
+ data: {
+ series: ["#2A8EFD", "#03C883", "#FFC93F", "#FF8228", "#FF2929"],
+ seriesFont: ["#FFFFFF", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#FFFFFF"],
+ },
+ font: {
+ colors: {
+ light: {
+ primary: "#000000",
+ secondary: "#111111",
+ },
+ dark: {
+ primary: "#FFFFFF",
+ secondary: "#EEEEEE",
+ },
+ },
+ },
+ surfaces: {
+ light: {
+ background: "#FFFFFF",
+ border: "#E0E0E0",
+ graph: "#FFFFFF",
+ graphBorder: "#E0E0E0",
+ },
+ grey: {
+ background: "#F4F5F9",
+ border: "#E0E0E0",
+ graph: "#F4F5F9",
+ graphBorder: "#E0E0E0",
+ },
+ dark: {
+ background: "#000000",
+ border: "#000000",
+ graph: "#000000",
+ graphBorder: "#000000",
+ },
+ },
+};
+
+const styles = {
+ font: {
+ properties: textFontProperties,
+ sizes: {
+ small: {
+ title: "h5",
+ subTitle: "caption",
+ axisLabels: "body1",
+ axisTicks: "body2",
+ },
+ normal: {
+ title: "h4",
+ subTitle: "body2",
+ axisLabels: "body1",
+ axisTicks: "body2",
+ },
+ large: {
+ title: "h3",
+ subTitle: "body1",
+ axisLabels: "body1",
+ axisTicks: "body2",
+ },
+ },
+ },
+ spacing: {
+ outerPadding: 24,
+ headingMargin: 24,
+ titleSubTitleMargin: 16,
+ },
+};
+
+export default {
+ colors,
+ styles,
+ functions: {
+ hexShade: (index, percent) => shadeColorHex(series[index], percent),
+ hexAlpha: setAlphaHex,
+ decimalToHex,
+ chartSchemeColor: (scheme, type) => {
+ if (type === "text" || type === "textPrimary") {
+ return scheme === "light" || scheme === "grey"
+ ? colors.font.colors.light.primary
+ : colors.font.colors.dark.primary;
+ }
+
+ if (type === "textSecondary") {
+ return scheme === "light" || scheme === "grey"
+ ? colors.font.colors.light.secondary
+ : colors.font.colors.dark.secondary;
+ }
+
+ if (type === "background") {
+ return scheme === "light"
+ ? colors.surfaces.light.background
+ : scheme === "grey"
+ ? colors.surfaces.grey.background
+ : colors.surfaces.dark.background;
+ }
+
+ if (type === "border") {
+ return scheme === "light"
+ ? colors.surfaces.light.border
+ : scheme === "grey"
+ ? colors.surfaces.grey.border
+ : colors.surfaces.dark.border;
+ }
+
+ if (type === "graph") {
+ return scheme === "light"
+ ? colors.surfaces.light.graph
+ : scheme === "grey"
+ ? colors.surfaces.grey.graph
+ : colors.surfaces.dark.graph;
+ }
+
+ if (type === "graphBorder") {
+ return scheme === "light"
+ ? colors.surfaces.light.graphBorder
+ : scheme === "grey"
+ ? colors.surfaces.grey.graphBorder
+ : colors.surfaces.dark.graphBorder;
+ }
+ },
+ },
+};
diff --git a/src/components/graphs/tradeoff-triangle/index.jsx b/src/components/graphs/tradeoff-triangle/index.jsx
new file mode 100644
index 00000000000..0ac3d60044c
--- /dev/null
+++ b/src/components/graphs/tradeoff-triangle/index.jsx
@@ -0,0 +1,121 @@
+import React from "react";
+
+import theme from "../theme";
+import { Point, Line, Triangle, Polygon } from "../vector";
+import { pointsToPathD, createText } from "../svg";
+
+const NeuralMagicTradeoffTriangle = ({
+ width = null,
+ height = 480,
+ spacing = 4,
+ colorsStartIndex = 2,
+ firstLabel = "Tradeoff One",
+ secondLabel = "Tradeoff Two",
+ thirdLabel = "Tradeoff Three",
+ labelSize = 32,
+}) => {
+ // if (width && !height) {
+ // height = 0.5 * Math.sqrt(3) * width;
+ // } else if (!width && height) {
+ // width = 2 * (1 / Math.sqrt(3)) * height;
+ // } else if (!width && !height) {
+ // console.error(
+ // "Either height or width must be given for NeuralMagicTradeoffTriangle",
+ // );
+ // return
;
+ // }
+ //
+ // const triangle = new Triangle(
+ // new Point(0, height),
+ // new Point(width / 2, 0),
+ // new Point(width, height),
+ // );
+ // const tradeoffTop = new Polygon([
+ // triangle.pointB.clone(), // Top of triangle
+ // triangle.edgeBC.pointAt(
+ // (triangle.edgeBC.length() * 0.5 - spacing / 2) / triangle.edgeBC.length(),
+ // ), // Right side midpoint
+ // new Line(triangle.centroid, triangle.pointB).pointAt(
+ // spacing / 2 / triangle.centroid.distance(triangle.pointB),
+ // ), // Centroid
+ // triangle.edgeAB.pointAt(
+ // (triangle.edgeAB.length() * 0.5 + spacing / 2) / triangle.edgeAB.length(),
+ // ), // Left side midpoint
+ // ]);
+ // const tradeoffRight = new Polygon([
+ // triangle.edgeBC.pointAt(
+ // (triangle.edgeBC.length() * 0.5 + spacing / 2) / triangle.edgeBC.length(),
+ // ), // Right side midpoint
+ // triangle.pointC.clone(), // Right corner
+ // triangle.edgeCA.pointAt(
+ // (triangle.edgeCA.length() * 0.5 - spacing / 2) / triangle.edgeCA.length(),
+ // ), // Bottom side midpoint
+ // new Line(triangle.centroid, triangle.pointC).pointAt(
+ // spacing / 2 / triangle.centroid.distance(triangle.pointC),
+ // ), // Centroid
+ // ]);
+ // const tradeoffLeft = new Polygon([
+ // triangle.edgeCA.pointAt(
+ // (triangle.edgeCA.length() * 0.5 + spacing / 2) / triangle.edgeCA.length(),
+ // ), // Bottom side midpoint
+ // triangle.pointA.clone(), // Left corner
+ // triangle.edgeAB.pointAt(
+ // (triangle.edgeAB.length() * 0.5 - spacing / 2) / triangle.edgeAB.length(),
+ // ), // Left side midpoint
+ // new Line(triangle.centroid, triangle.pointA).pointAt(
+ // spacing / 2 / triangle.centroid.distance(triangle.pointA),
+ // ), // Centroid
+ // ]);
+ //
+ // console.log(tradeoffTop);
+ //
+ // return (
+ //
+ //
+ //
+ //
+ //
+ // {createText(
+ // firstLabel,
+ // tradeoffTop.center.x,
+ // tradeoffTop.center.y,
+ // 0.7 * tradeoffTop.width(),
+ // "middle",
+ // labelSize,
+ // "body",
+ // colors.seriesText[colorsStartIndex % colors.seriesText.length],
+ // )}
+ // {createText(
+ // secondLabel,
+ // tradeoffRight.center.x,
+ // tradeoffRight.center.y,
+ // 0.7 * tradeoffRight.width(),
+ // "middle",
+ // labelSize,
+ // "body",
+ // colors.seriesText[(colorsStartIndex + 1) % colors.seriesText.length],
+ // )}
+ // {createText(
+ // thirdLabel,
+ // tradeoffLeft.center.x,
+ // tradeoffLeft.center.y,
+ // 0.7 * tradeoffLeft.width(),
+ // "middle",
+ // labelSize,
+ // "body",
+ // colors.seriesText[(colorsStartIndex + 2) % colors.seriesText.length],
+ // )}
+ //
+ // );
+};
+
+export default NeuralMagicTradeoffTriangle;
diff --git a/src/components/graphs/utilities.jsx b/src/components/graphs/utilities.jsx
new file mode 100644
index 00000000000..93819187886
--- /dev/null
+++ b/src/components/graphs/utilities.jsx
@@ -0,0 +1,64 @@
+import SHA256 from "crypto-js/sha256";
+import theme from "./theme";
+
+const hashObjects = (objects, length = 32) => {
+ const combinedString = JSON.stringify(objects);
+
+ return SHA256(combinedString).toString().substring(0, length);
+};
+
+const stringFormat = (value, valuesFormat) => {
+ try {
+ return value.toLocaleString(undefined, {
+ minimumFractionDigits:
+ valuesFormat === "#" ? 0 : valuesFormat.split(".")[1].length,
+ maximumFractionDigits:
+ valuesFormat === "#" ? 0 : valuesFormat.split(".")[1].length,
+ });
+ } catch (error) {
+ console.error("Invalid valuesFormat:", valuesFormat);
+ return value;
+ }
+};
+
+const textDimensions = (text, style) => {
+ const fontProperties = theme.styles.font.properties[style];
+ const canvas = document.createElement("canvas");
+ const context = canvas.getContext("2d");
+ context.font = `${fontProperties.fontStyle} ${fontProperties.fontWeight} ${fontProperties.fontSize} ${fontProperties.fontFamily}`;
+ const metrics = context.measureText(text);
+ const width = metrics.width;
+ const height =
+ metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
+
+ return { width, height };
+};
+
+const splitText = (text, maxWidth, style) => {
+ text = text + ""; // Ensure text is a string
+ const words = text.split(" ");
+ const lines = [];
+ let line = "";
+
+ for (const word of words) {
+ const testLine = line ? `${line} ${word}` : word;
+ const { width } = textDimensions(testLine, style);
+
+ if (width <= maxWidth) {
+ line = testLine;
+ } else {
+ lines.push(line);
+ line = word;
+ }
+ }
+
+ lines.push(line);
+ const dimensions = lines.map((line) => textDimensions(line, style));
+
+ return {
+ lines,
+ dimensions,
+ };
+};
+
+export { hashObjects, stringFormat, textDimensions, splitText };
diff --git a/src/components/graphs/vector.jsx b/src/components/graphs/vector.jsx
new file mode 100644
index 00000000000..a854014fd98
--- /dev/null
+++ b/src/components/graphs/vector.jsx
@@ -0,0 +1,431 @@
+class Point {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ equals(otherPoint) {
+ return this.x === otherPoint.x && this.y === otherPoint.y;
+ }
+
+ toString() {
+ return `(${this.x}, ${this.y})`;
+ }
+
+ clone() {
+ return new Point(this.x, this.y);
+ }
+
+ normalize() {
+ const magnitude = Math.sqrt(this.x * this.x + this.y * this.y);
+ if (magnitude === 0) return; // Avoid division by zero
+ this.x /= magnitude;
+ this.y /= magnitude;
+ }
+
+ rotate(angle) {
+ const radians = (angle * Math.PI) / 180;
+ const newX = this.x * Math.cos(radians) - this.y * Math.sin(radians);
+ const newY = this.x * Math.sin(radians) + this.y * Math.cos(radians);
+ this.x = newX;
+ this.y = newY;
+ }
+
+ add(otherPoint) {
+ this.x += otherPoint.x;
+ this.y += otherPoint.y;
+ }
+
+ subtract(otherPoint) {
+ this.x -= otherPoint.x;
+ this.y -= otherPoint.y;
+ }
+
+ multiply(scalar) {
+ this.x *= scalar;
+ this.y *= scalar;
+ }
+
+ divide(scalar) {
+ if (scalar === 0) return; // Avoid division by zero
+ this.x /= scalar;
+ this.y /= scalar;
+ }
+
+ distance(otherPoint) {
+ const dx = this.x - otherPoint.x;
+ const dy = this.y - otherPoint.y;
+ return Math.sqrt(dx * dx + dy * dy);
+ }
+}
+
+class Line {
+ constructor(start, end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ equals(otherLine) {
+ return this.start.equals(otherLine.start) && this.end.equals(otherLine.end);
+ }
+
+ toString() {
+ return `[${this.start}, ${this.end}]`;
+ }
+
+ clone() {
+ return new Line(this.start.clone(), this.end.clone());
+ }
+
+ length() {
+ return this.start.distance(this.end);
+ }
+
+ slope() {
+ const dx = this.end.x - this.start.x;
+ const dy = this.end.y - this.start.y;
+ if (dx === 0) return Infinity;
+ return dy / dx;
+ }
+
+ shift(dx, dy) {
+ this.start.x += dx;
+ this.start.y += dy;
+ this.end.x += dx;
+ this.end.y += dy;
+ }
+
+ scale(factor, relativeTo = new Point(0, 0)) {
+ // Scale relative to a point (default is the origin)
+ this.start.x = relativeTo.x + factor * (this.start.x - relativeTo.x);
+ this.start.y = relativeTo.y + factor * (this.start.y - relativeTo.y);
+ this.end.x = relativeTo.x + factor * (this.end.x - relativeTo.x);
+ this.end.y = relativeTo.y + factor * (this.end.y - relativeTo.y);
+ }
+
+ rotate(angle, relativeTo = new Point(0, 0)) {
+ const translation = new Point(-relativeTo.x, -relativeTo.y);
+ this.start.add(translation);
+ this.end.add(translation);
+ this.start.rotate(angle);
+ this.end.rotate(angle);
+ translation.multiply(-1);
+ this.start.add(translation);
+ this.end.add(translation);
+ }
+
+ midPoint() {
+ return new Point(
+ (this.start.x + this.end.x) / 2,
+ (this.start.y + this.end.y) / 2,
+ );
+ }
+
+ pointAt(t) {
+ if (t < 0 || t > 1) return null;
+
+ return new Point(
+ this.start.x + t * (this.end.x - this.start.x),
+ this.start.y + t * (this.end.y - this.start.y),
+ );
+ }
+
+ isParallel(otherLine) {
+ return this.slope() === otherLine.slope();
+ }
+
+ isPerpendicular(otherLine) {
+ return this.slope() * otherLine.slope() === -1;
+ }
+
+ intersection(otherLine) {
+ const x1 = this.start.x;
+ const y1 = this.start.y;
+ const x2 = this.end.x;
+ const y2 = this.end.y;
+ const x3 = otherLine.start.x;
+ const y3 = otherLine.start.y;
+ const x4 = otherLine.end.x;
+ const y4 = otherLine.end.y;
+
+ const denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
+ if (denominator === 0) return null; // Lines are parallel or coincident
+
+ const t = ((x3 - x4) * (y1 - y3) + (y3 - y4) * (x1 - x3)) / denominator;
+ const u = ((x1 - x2) * (y1 - y3) + (y1 - y2) * (x3 - x1)) / denominator;
+
+ if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
+ const intersectionX = x1 + t * (x2 - x1);
+ const intersectionY = y1 + t * (y2 - y1);
+ return new Point(intersectionX, intersectionY);
+ }
+
+ return null; // Lines don't intersect within their defined segments
+ }
+
+ dotProduct(otherLine) {
+ const dx1 = this.end.x - this.start.x;
+ const dy1 = this.end.y - this.start.y;
+ const dx2 = otherLine.end.x - otherLine.start.x;
+ const dy2 = otherLine.end.y - otherLine.start.y;
+ return dx1 * dx2 + dy1 * dy2;
+ }
+
+ angle() {
+ const dx = this.end.x - this.start.x;
+ const dy = this.end.y - this.start.y;
+ return (Math.atan2(dy, dx) * 180) / Math.PI;
+ }
+}
+
+class Triangle {
+ constructor(pointA, pointB, pointC) {
+ this.pointA = pointA;
+ this.pointB = pointB;
+ this.pointC = pointC;
+ this.edgeAB = new Line(pointA, pointB);
+ this.edgeBC = new Line(pointB, pointC);
+ this.edgeCA = new Line(pointC, pointA);
+ this.recalculateDerivedProperties(); // Initialize values
+ }
+
+ recalculateDerivedProperties() {
+ // Angles (using Law of Cosines)
+ const a = this.edgeBC.length();
+ const b = this.edgeCA.length();
+ const c = this.edgeAB.length();
+ this.angleA =
+ (Math.acos((b * b + c * c - a * a) / (2 * b * c)) * 180) / Math.PI;
+ this.angleB =
+ (Math.acos((a * a + c * c - b * b) / (2 * a * c)) * 180) / Math.PI;
+ this.angleC = 180 - this.angleA - this.angleB;
+
+ // Centroid (average of vertices)
+ this.centroid = new Point(
+ (this.pointA.x + this.pointB.x + this.pointC.x) / 3,
+ (this.pointA.y + this.pointB.y + this.pointC.y) / 3,
+ );
+ }
+
+ equals(otherTriangle) {
+ const points1 = [this.pointA, this.pointB, this.pointC].sort((a, b) => {
+ if (a.x === b.x) return a.y - b.y;
+ return a.x - b.x;
+ });
+
+ const points2 = [
+ otherTriangle.pointA,
+ otherTriangle.pointB,
+ otherTriangle.pointC,
+ ].sort((a, b) => {
+ if (a.x === b.x) return a.y - b.y;
+ return a.x - b.x;
+ });
+
+ return (
+ points1[0].equals(points2[0]) &&
+ points1[1].equals(points2[1]) &&
+ points1[2].equals(points2[2])
+ );
+ }
+
+ toString() {
+ return `Triangle: ${this.pointA}, ${this.pointB}, ${this.pointC}`;
+ }
+
+ clone() {
+ return new Triangle(
+ this.pointA.clone(),
+ this.pointB.clone(),
+ this.pointC.clone(),
+ );
+ }
+
+ perimeter() {
+ return this.edgeAB.length() + this.edgeBC.length() + this.edgeCA.length();
+ }
+
+ area() {
+ const s = this.perimeter() / 2;
+ return Math.sqrt(
+ s *
+ (s - this.edgeAB.length()) *
+ (s - this.edgeBC.length()) *
+ (s - this.edgeCA.length()),
+ );
+ }
+}
+
+class Polygon {
+ constructor(points) {
+ this.points = points;
+ this.recalculateDerivedProperties();
+ }
+
+ recalculateDerivedProperties() {
+ this.edges = this.calculateEdges();
+ this.angles = this.calculateAngles();
+ this.center = this.calculateCentroid();
+ }
+
+ calculateEdges() {
+ const edges = [];
+ for (let i = 0; i < this.points.length; i++) {
+ edges.push(
+ new Line(this.points[i], this.points[(i + 1) % this.points.length]),
+ );
+ }
+ return edges;
+ }
+
+ calculateAngles() {
+ // ... (Implementation to calculate angles using vectors and trigonometry)
+ }
+
+ calculateCentroid() {
+ let sumX = 0;
+ let sumY = 0;
+ for (const point of this.points) {
+ sumX += point.x;
+ sumY += point.y;
+ }
+ return new Point(sumX / this.points.length, sumY / this.points.length);
+ }
+
+ equals(otherPolygon) {
+ if (this.points.length !== otherPolygon.points.length) return false;
+
+ // Find the starting point with the smallest coordinates in both polygons
+ let minIndex1 = 0,
+ minIndex2 = 0;
+ for (let i = 1; i < this.points.length; i++) {
+ if (
+ this.points[i].y < this.points[minIndex1].y ||
+ (this.points[i].y === this.points[minIndex1].y &&
+ this.points[i].x < this.points[minIndex1].x)
+ ) {
+ minIndex1 = i;
+ }
+ if (
+ otherPolygon.points[i].y < otherPolygon.points[minIndex2].y ||
+ (otherPolygon.points[i].y === otherPolygon.points[minIndex2].y &&
+ otherPolygon.points[i].x < otherPolygon.points[minIndex2].x)
+ ) {
+ minIndex2 = i;
+ }
+ }
+
+ // Create sorted arrays of points, starting from the smallest coordinate
+ const sortedPoints1 = this.getSortedPointsFromIndex(minIndex1);
+ const sortedPoints2 = otherPolygon.getSortedPointsFromIndex(minIndex2);
+
+ // Compare sorted points
+ for (let i = 0; i < sortedPoints1.length; i++) {
+ if (!sortedPoints1[i].equals(sortedPoints2[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ toString() {
+ return `Polygon: ${this.points.map((p) => p.toString()).join(", ")}`;
+ }
+
+ clone() {
+ return new Polygon(this.points.map((p) => p.clone()));
+ }
+
+ getSortedPointsFromIndex(startIndex) {
+ const sortedPoints = this.points
+ .slice(startIndex)
+ .concat(this.points.slice(0, startIndex));
+ return sortedPoints.sort((a, b) => a.x - b.x || a.y - b.y); // Sort by x, then y
+ }
+
+ width() {
+ const xCoordinates = this.points.map((point) => point.x);
+ return Math.max(...xCoordinates) - Math.min(...xCoordinates);
+ }
+
+ height() {
+ const yCoordinates = this.points.map((point) => point.y);
+ return Math.max(...yCoordinates) - Math.min(...yCoordinates);
+ }
+
+ perimeter() {
+ return this.edges.reduce((sum, edge) => sum + edge.length(), 0);
+ }
+
+ area() {
+ let area = 0;
+
+ for (let i = 1; i < this.points.length - 1; i++) {
+ const triangle = new Triangle(
+ this.points[0],
+ this.points[i],
+ this.points[i + 1],
+ );
+ area += triangle.area();
+ }
+
+ return Math.abs(area);
+ }
+
+ isSquare() {
+ if (this.points.length !== 4) return false;
+
+ const side1 = this.edges[0].length();
+
+ for (let i = 1; i < 4; i++) {
+ if (this.edges[i].length() !== side1) return false;
+ }
+
+ for (let i = 0; i < 4; i++) {
+ const v1 = this.edges[i].end.clone().subtract(this.edges[i].start);
+ const v2 = this.edges[(i + 1) % 4].end
+ .clone()
+ .subtract(this.edges[(i + 1) % 4].start);
+ if (v1.dotProduct(v2) === 0) return true;
+ }
+
+ return false;
+ }
+
+ isRectangle() {
+ if (this.points.length !== 4) return false;
+
+ if (
+ !this.edges[0].isParallel(this.edges[2]) ||
+ !this.edges[1].isParallel(this.edges[3])
+ ) {
+ return false;
+ }
+
+ for (let i = 0; i < 4; i++) {
+ const v1 = this.edges[i].end.clone().subtract(this.edges[i].start);
+ const v2 = this.edges[(i + 1) % 4].end
+ .clone()
+ .subtract(this.edges[(i + 1) % 4].start);
+ if (v1.dotProduct(v2) === 0) return true;
+ }
+
+ return false;
+ }
+}
+
+class Rectangle extends Polygon {
+ constructor(x, y, width, height) {
+ super([
+ new Point(x, y),
+ new Point(x + width, y),
+ new Point(x + width, y + height),
+ new Point(x, y + height),
+ ]);
+
+ this.x = x;
+ this.y = y;
+ }
+}
+
+export { Point, Line, Triangle, Polygon, Rectangle };
diff --git a/src/components/mdx-provider/index.jsx b/src/components/mdx-provider/index.jsx
deleted file mode 100644
index fd6d7a46d39..00000000000
--- a/src/components/mdx-provider/index.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import { MDXProvider } from '@mdx-js/react';
-
-
-
-const components = {
-
-};
-
-export default function DocsMDXProvider({ children }) {
- return
{children} ;
-}
diff --git a/src/components/version-injector/index.jsx b/src/components/version-injector/index.jsx
index b860a0d5876..4ac14693b18 100644
--- a/src/components/version-injector/index.jsx
+++ b/src/components/version-injector/index.jsx
@@ -1,66 +1,124 @@
-import React from 'react';
-import {useDoc} from '@docusaurus/theme-common/internal';
-import usePluginData from '@docusaurus/useGlobalData';
+import React from "react";
+import { useDoc } from "@docusaurus/theme-common/internal";
+import usePluginData from "@docusaurus/useGlobalData";
+const processChildren = (
+ child,
+ currentVersion,
+ lastVersion,
+ targetVersion,
+ targetProducts,
+ prepend,
+ currentTag,
+ ignoreNightly,
+) => {
+ if (typeof child === "string") {
+ let version = currentVersion;
+ let products = [...targetProducts];
-const processChildren = (child, currentVersion, lastVersion, targetVersion, targetProducts, prepend, currentTag, ignoreNightly) => {
- if (typeof child === 'string') {
- let version = currentVersion;
- let products = [...targetProducts];
-
- if (version === 'current') {
- if (!ignoreNightly && targetProducts) {
- for (let i = 0; i < products.length; i++) {
- let product = products[i];
- if (product.indexOf("[") > -1) {
- const split = product.split('[');
- product = `${split[0]}-nightly[${split[1]}`;
- } else {
- product = `${product}-nightly`;
- }
- products[i] = product;
- }
- }
- version = currentTag;
- } else if (version === lastVersion) {
- version = '';
- } else if (prepend) {
- version = `${prepend}${version}`;
- }
-
- let replaced = child.replace(new RegExp(targetVersion, 'g'), version);
-
+ if (version === "current") {
+ if (!ignoreNightly && targetProducts) {
for (let i = 0; i < products.length; i++) {
- replaced = replaced.replace(new RegExp(targetProducts[i].replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), products[i]);
+ let product = products[i];
+ if (product.indexOf("[") > -1) {
+ const split = product.split("[");
+ product = `${split[0]}-nightly[${split[1]}`;
+ } else {
+ product = `${product}-nightly`;
+ }
+ products[i] = product;
}
-
- return replaced;
+ }
+ version = currentTag;
+ } else if (version === lastVersion) {
+ version = "";
+ } else if (prepend) {
+ version = `${prepend}${version}`;
}
- if (React.isValidElement(child)) {
- return React.cloneElement(child, child.props, processChildren(child.props.children, currentVersion, lastVersion, targetVersion, targetProducts, prepend, currentTag, ignoreNightly));
- }
+ let replaced = child.replace(new RegExp(targetVersion, "g"), version);
- if (Array.isArray(child)) {
- return child.map(c => processChildren(c, currentVersion, lastVersion, targetVersion, targetProducts, prepend, currentTag, ignoreNightly));
+ for (let i = 0; i < products.length; i++) {
+ replaced = replaced.replace(
+ new RegExp(
+ targetProducts[i].replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
+ "g",
+ ),
+ products[i],
+ );
}
- return child;
-};
+ return replaced;
+ }
+
+ if (React.isValidElement(child)) {
+ return React.cloneElement(
+ child,
+ child.props,
+ processChildren(
+ child.props.children,
+ currentVersion,
+ lastVersion,
+ targetVersion,
+ targetProducts,
+ prepend,
+ currentTag,
+ ignoreNightly,
+ ),
+ );
+ }
+ if (Array.isArray(child)) {
+ return child.map((c) =>
+ processChildren(
+ c,
+ currentVersion,
+ lastVersion,
+ targetVersion,
+ targetProducts,
+ prepend,
+ currentTag,
+ ignoreNightly,
+ ),
+ );
+ }
+
+ return child;
+};
-const VersionInjector = ({ children, targetVersion = 'VERSION', targetProduct = 'PRODUCT', prepend = '', currentTag = '', ignoreNightly = false, ignoreLastVersion = false}) => {
- const { metadata } = useDoc();
- const pluginData = usePluginData('docusaurus-plugin-content-docs')['docusaurus-plugin-content-docs'];
- const versions = pluginData.default.versions;
- const lastVersionData = versions.find(version => version.isLast);
- const lastVersion = ignoreLastVersion ? null : lastVersionData.name;
+const VersionInjector = ({
+ children,
+ targetVersion = "VERSION",
+ targetProduct = "PRODUCT",
+ prepend = "",
+ currentTag = "",
+ ignoreNightly = false,
+ ignoreLastVersion = false,
+}) => {
+ const { metadata } = useDoc();
+ const pluginData = usePluginData("docusaurus-plugin-content-docs")[
+ "docusaurus-plugin-content-docs"
+ ];
+ const versions = pluginData.default.versions;
+ const lastVersionData = versions.find((version) => version.isLast);
+ const lastVersion = ignoreLastVersion ? null : lastVersionData.name;
- const currentVersion = metadata.version;
- const targetProducts = Array.isArray(targetProduct) ? targetProduct : [targetProduct];
- const processedChildren = processChildren(children, currentVersion, lastVersion, targetVersion, targetProducts, prepend, currentTag, ignoreNightly);
+ const currentVersion = metadata.version;
+ const targetProducts = Array.isArray(targetProduct)
+ ? targetProduct
+ : [targetProduct];
+ const processedChildren = processChildren(
+ children,
+ currentVersion,
+ lastVersion,
+ targetVersion,
+ targetProducts,
+ prepend,
+ currentTag,
+ ignoreNightly,
+ );
- return <>{processedChildren}>;
+ return <>{processedChildren}>;
};
-export default VersionInjector;
\ No newline at end of file
+export default VersionInjector;
diff --git a/src/css/_mixins.scss b/src/css/_mixins.scss
index fe2392d509b..952c9ba9184 100644
--- a/src/css/_mixins.scss
+++ b/src/css/_mixins.scss
@@ -5,4 +5,4 @@
-webkit-box-orient: vertical;
text-overflow: ellipsis;
white-space: unset;
-}
\ No newline at end of file
+}
diff --git a/src/css/_screen-layouts.scss b/src/css/_screen-layouts.scss
index a23634e5321..8d5f8cf1110 100644
--- a/src/css/_screen-layouts.scss
+++ b/src/css/_screen-layouts.scss
@@ -110,4 +110,4 @@ $columns-right-bar: 0;
@include layout-xl;
@content;
}
-}
\ No newline at end of file
+}
diff --git a/src/css/custom.scss b/src/css/custom.scss
index edd568778c7..37daa4a9586 100644
--- a/src/css/custom.scss
+++ b/src/css/custom.scss
@@ -1,9 +1,30 @@
-@import '_screen-layouts';
+@import "_screen-layouts";
-html, :root {
+@font-face {
+ font-family: "Spezia";
+ src: url("/fonts/SpeziaWeb-Regular.woff") format("woff");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: "Spezia Medium";
+ src: url("/fonts/SpeziaWeb-Medium.woff") format("woff");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: "Spezia Mono";
+ src: url("/fonts/SpeziaMonoWeb-Medium.woff") format("woff");
+ font-weight: normal;
+ font-style: normal;
+}
+html,
+:root {
/* Heading Fonts */
- --ifm-heading-font-family: 'Space Grotesk', sans-serif;
+ --ifm-heading-font-family: "Space Grotesk", sans-serif;
--ifm-heading-font-weight: 400;
--ifm-h1-font-size: 48px;
--ifm-h2-font-size: 32px;
@@ -13,20 +34,20 @@ html, :root {
--ifm-h6-font-size: 18px;
/* Content Fonts */
- --ifm-font-family-base: 'Inter', sans-serif;
+ --ifm-font-family-base: "Inter", sans-serif;
--ifm-font-size-base: 16px; /* Body 1 */
--ifm-font-weight-semibold: 600;
--ifm-link-hover-decoration: underline;
/* Text Colors */
--ifm-font-color-base: #222222;
- --ifm-color-content-secondary: #5D6C6D;
+ --ifm-color-content-secondary: #5d6c6d;
--ifm-font-color-base-inverse: #ffffff;
--ifm-link-color: #3d86b7;
/* Background / Surface Colors */
--ifm-background-color: #f6fbfe;
- --custom-background-blue-dark: #052D52;
+ --custom-background-blue-dark: #052d52;
--custom-background-blue-light: #e1f0fd;
--custom-surface-color: #fdfdfe;
--custom-surface-blue: #c5eefb;
@@ -58,7 +79,8 @@ Layouts
*/
@include for-xl-screens {
- html, :root {
+ html,
+ :root {
--gutter: 32px;
--margin: auto;
--margin-px: calc(100vw - 1600px) / 2;
@@ -74,7 +96,8 @@ Layouts
}
@include for-lg-screens {
- html, :root {
+ html,
+ :root {
--gutter: 32px;
--margin: 32px;
--margin-px: 32px;
@@ -90,7 +113,8 @@ Layouts
}
@include for-md-screens {
- html, :root {
+ html,
+ :root {
--gutter: 16px;
--margin: 32px;
--margin-px: 16px;
@@ -106,7 +130,8 @@ Layouts
}
@include for-sm-screens {
- html, :root {
+ html,
+ :root {
--gutter: 16px;
--margin: 32px;
--columns: 4;
@@ -121,7 +146,8 @@ Layouts
}
@include for-xs-screens {
- html, :root {
+ html,
+ :root {
--gutter: 8px;
--margin: 16px;
--columns: 4;
@@ -135,7 +161,6 @@ Layouts
}
}
-
/**
Navbar customizations
*/
@@ -156,7 +181,9 @@ Navbar customizations
margin-right: var(--margin);
}
-.navbar__title, .navbar__inner, .navbar__link {
+.navbar__title,
+.navbar__inner,
+.navbar__link {
color: var(--ifm-font-color-base-inverse);
}
@@ -182,7 +209,7 @@ Search customizations
/* Modal */
/*--docsearch-container-background: var(--custom-surface-color);*/
--docsearch-modal-background: var(--ifm-background-color);
- --docsearch-footer-background: var(--ifm-background-color)
+ --docsearch-footer-background: var(--ifm-background-color);
}
.DocSearch-Button-Keys {
@@ -195,7 +222,6 @@ Search customizations
width: 128px;
}
-
/**
Left nav cutomizations
*/
@@ -207,12 +233,12 @@ Left nav cutomizations
padding-top: 16px;
}
-.theme-doc-sidebar-item-category, .theme-doc-sidebar-item-link {
+.theme-doc-sidebar-item-category,
+.theme-doc-sidebar-item-link {
font-size: var(--ifm-h4-font-size);
font-family: var(--ifm-heading-font-family);
}
-
/**
Footer customizations
*/
@@ -231,7 +257,8 @@ Footer customizations
padding-bottom: 20px;
}
- .footer__links, .footer__bottom {
+ .footer__links,
+ .footer__bottom {
margin: 0;
text-align: start;
}
@@ -245,7 +272,6 @@ Footer customizations
}
}
-
/**
Right bar customizations
*/
@@ -259,7 +285,7 @@ Right bar customizations
.table-of-contents {
padding: 0;
border-left: none;
- font-size: 1.0rem;
+ font-size: 1rem;
li {
margin: 8px 0;
diff --git a/src/theme/CodeBlock/Container/index.js b/src/theme/CodeBlock/Container/index.js
index ce665eb41bc..b95288a7296 100644
--- a/src/theme/CodeBlock/Container/index.js
+++ b/src/theme/CodeBlock/Container/index.js
@@ -1,9 +1,9 @@
-import React from 'react';
-import clsx from 'clsx';
-import {ThemeClassNames, usePrismTheme} from '@docusaurus/theme-common';
-import {getPrismCssVariables} from '@docusaurus/theme-common/internal';
-import styles from './styles.module.css';
-export default function CodeBlockContainer({as: As, ...props}) {
+import React from "react";
+import clsx from "clsx";
+import { ThemeClassNames, usePrismTheme } from "@docusaurus/theme-common";
+import { getPrismCssVariables } from "@docusaurus/theme-common/internal";
+import styles from "./styles.module.css";
+export default function CodeBlockContainer({ as: As, ...props }) {
const prismTheme = usePrismTheme();
const prismCssVariables = getPrismCssVariables(prismTheme);
return (
diff --git a/src/theme/CodeBlock/Content/Element.js b/src/theme/CodeBlock/Content/Element.js
index dbe56049709..4e4e1b59383 100644
--- a/src/theme/CodeBlock/Content/Element.js
+++ b/src/theme/CodeBlock/Content/Element.js
@@ -1,16 +1,17 @@
-import React from 'react';
-import clsx from 'clsx';
-import Container from '@theme/CodeBlock/Container';
-import styles from './styles.module.css';
+import React from "react";
+import clsx from "clsx";
+import Container from "@theme/CodeBlock/Container";
+import styles from "./styles.module.css";
//
tags in markdown map to CodeBlocks. They may contain JSX children. When
// the children is not a simple string, we just return a styled block without
// actually highlighting.
-export default function CodeBlockJSX({children, className}) {
+export default function CodeBlockJSX({ children, className }) {
return (
+ className={clsx(styles.codeBlockStandalone, "thin-scrollbar", className)}
+ >
{children}
);
diff --git a/src/theme/CodeBlock/Content/String.js b/src/theme/CodeBlock/Content/String.js
index f16474b96f8..4e5e409e510 100644
--- a/src/theme/CodeBlock/Content/String.js
+++ b/src/theme/CodeBlock/Content/String.js
@@ -1,19 +1,19 @@
-import React from 'react';
-import clsx from 'clsx';
-import {useThemeConfig, usePrismTheme} from '@docusaurus/theme-common';
+import React from "react";
+import clsx from "clsx";
+import { useThemeConfig, usePrismTheme } from "@docusaurus/theme-common";
import {
parseCodeBlockTitle,
parseLanguage,
parseLines,
containsLineNumbers,
useCodeWordWrap,
-} from '@docusaurus/theme-common/internal';
-import {Highlight} from 'prism-react-renderer';
-import Line from '@theme/CodeBlock/Line';
-import CopyButton from '@theme/CodeBlock/CopyButton';
-import WordWrapButton from '@theme/CodeBlock/WordWrapButton';
-import Container from '@theme/CodeBlock/Container';
-import styles from './styles.module.css';
+} from "@docusaurus/theme-common/internal";
+import { Highlight } from "prism-react-renderer";
+import Line from "@theme/CodeBlock/Line";
+import CopyButton from "@theme/CodeBlock/CopyButton";
+import WordWrapButton from "@theme/CodeBlock/WordWrapButton";
+import Container from "@theme/CodeBlock/Container";
+import styles from "./styles.module.css";
// Prism languages are always lowercase
// We want to fail-safe and allow both "php" and "PHP"
@@ -23,30 +23,34 @@ function normalizeLanguage(language) {
}
function parseOutput(content) {
- if (!content.includes('') || !content.includes(' ')) {
+ if (!content.includes("") || !content.includes(" ")) {
return { code: content, output: null };
}
const codeRegex = /.*([\s\S]*?)<\/output>/i;
- const code = content.replace(codeRegex, '').trim();
+ const code = content.replace(codeRegex, "").trim();
let output = content.match(codeRegex)?.[1].trim();
const commentRegex = /^[ \t]*(\/\/|\/\*|\*\/|#|--)/gm;
- output = output.split('\n').map(line => line.replace(commentRegex, '')).join('\n').trim();
+ output = output
+ .split("\n")
+ .map((line) => line.replace(commentRegex, ""))
+ .join("\n")
+ .trim();
return { code, output };
}
export default function CodeBlockString({
children,
- className: blockClassName = '',
+ className: blockClassName = "",
metastring,
title: titleProp,
showLineNumbers: showLineNumbersProp,
language: languageProp,
}) {
const {
- prism: {defaultLanguage, magicComments},
+ prism: { defaultLanguage, magicComments },
} = useThemeConfig();
const language = normalizeLanguage(
languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage,
@@ -58,7 +62,7 @@ export default function CodeBlockString({
// "title=\"xyz\"" => title: "\"xyz\""
const title = parseCodeBlockTitle(metastring) || titleProp;
const parsedCode = parseOutput(children);
- const {lineClassNames, code} = parseLines(parsedCode.code, {
+ const { lineClassNames, code } = parseLines(parsedCode.code, {
metastring,
language,
magicComments,
@@ -73,22 +77,25 @@ export default function CodeBlockString({
language &&
!blockClassName.includes(`language-${language}`) &&
`language-${language}`,
- )}>
+ )}
+ >
{title && {title}
}
-
- {({className, style, tokens, getLineProps, getTokenProps}) => (
+
+ {({ className, style, tokens, getLineProps, getTokenProps }) => (
+ className={clsx(className, styles.codeBlock, "thin-scrollbar")}
+ style={style}
+ >
+ )}
+ >
{tokens.map((line, i) => (
{parsedCode.output && (
-
-
-
- {parsedCode.output}
-
+
+
+
+ {parsedCode.output}
+
)}
diff --git a/src/theme/CodeBlock/CopyButton/index.js b/src/theme/CodeBlock/CopyButton/index.js
index fd430b473cb..4f6c3b736b3 100644
--- a/src/theme/CodeBlock/CopyButton/index.js
+++ b/src/theme/CodeBlock/CopyButton/index.js
@@ -1,11 +1,11 @@
-import React, {useCallback, useState, useRef, useEffect} from 'react';
-import clsx from 'clsx';
-import copy from 'copy-text-to-clipboard';
-import {translate} from '@docusaurus/Translate';
-import IconCopy from '@theme/Icon/Copy';
-import IconSuccess from '@theme/Icon/Success';
-import styles from './styles.module.css';
-export default function CopyButton({code, className}) {
+import React, { useCallback, useState, useRef, useEffect } from "react";
+import clsx from "clsx";
+import copy from "copy-text-to-clipboard";
+import { translate } from "@docusaurus/Translate";
+import IconCopy from "@theme/Icon/Copy";
+import IconSuccess from "@theme/Icon/Success";
+import styles from "./styles.module.css";
+export default function CopyButton({ code, className }) {
const [isCopied, setIsCopied] = useState(false);
const copyTimeout = useRef(undefined);
const handleCopyCode = useCallback(() => {
@@ -22,28 +22,29 @@ export default function CopyButton({code, className}) {
aria-label={
isCopied
? translate({
- id: 'theme.CodeBlock.copied',
- message: 'Copied',
- description: 'The copied button label on code blocks',
+ id: "theme.CodeBlock.copied",
+ message: "Copied",
+ description: "The copied button label on code blocks",
})
: translate({
- id: 'theme.CodeBlock.copyButtonAriaLabel',
- message: 'Copy code to clipboard',
- description: 'The ARIA label for copy code blocks button',
+ id: "theme.CodeBlock.copyButtonAriaLabel",
+ message: "Copy code to clipboard",
+ description: "The ARIA label for copy code blocks button",
})
}
title={translate({
- id: 'theme.CodeBlock.copy',
- message: 'Copy',
- description: 'The copy button label on code blocks',
+ id: "theme.CodeBlock.copy",
+ message: "Copy",
+ description: "The copy button label on code blocks",
})}
className={clsx(
- 'clean-btn',
+ "clean-btn",
className,
styles.copyButton,
isCopied && styles.copyButtonCopied,
)}
- onClick={handleCopyCode}>
+ onClick={handleCopyCode}
+ >
diff --git a/src/theme/CodeBlock/Line/index.js b/src/theme/CodeBlock/Line/index.js
index f36761806ad..b0c2d8fbb37 100644
--- a/src/theme/CodeBlock/Line/index.js
+++ b/src/theme/CodeBlock/Line/index.js
@@ -1,6 +1,6 @@
-import React from 'react';
-import clsx from 'clsx';
-import styles from './styles.module.css';
+import React from "react";
+import clsx from "clsx";
+import styles from "./styles.module.css";
export default function CodeBlockLine({
line,
classNames,
@@ -8,15 +8,15 @@ export default function CodeBlockLine({
getLineProps,
getTokenProps,
}) {
- if (line.length === 1 && line[0].content === '\n') {
- line[0].content = '';
+ if (line.length === 1 && line[0].content === "\n") {
+ line[0].content = "";
}
const lineProps = getLineProps({
line,
className: clsx(classNames, showLineNumbers && styles.codeLine),
});
const lineTokens = line.map((token, key) => (
-
+
));
return (
diff --git a/src/theme/CodeBlock/Line/styles.module.css b/src/theme/CodeBlock/Line/styles.module.css
index 7c28ed9aa30..ef3aff97a8e 100644
--- a/src/theme/CodeBlock/Line/styles.module.css
+++ b/src/theme/CodeBlock/Line/styles.module.css
@@ -4,7 +4,7 @@ the background in custom CSS file due bug https://github.com/facebook/docusaurus
--docusaurus-highlighted-code-line-bg: rgb(72 77 91);
}
-:where([data-theme='dark']) {
+:where([data-theme="dark"]) {
--docusaurus-highlighted-code-line-bg: rgb(100 100 100);
}
diff --git a/src/theme/CodeBlock/WordWrapButton/index.js b/src/theme/CodeBlock/WordWrapButton/index.js
index 3a4136b6300..8881d6a23c1 100644
--- a/src/theme/CodeBlock/WordWrapButton/index.js
+++ b/src/theme/CodeBlock/WordWrapButton/index.js
@@ -1,26 +1,27 @@
-import React from 'react';
-import clsx from 'clsx';
-import {translate} from '@docusaurus/Translate';
-import IconWordWrap from '@theme/Icon/WordWrap';
-import styles from './styles.module.css';
-export default function WordWrapButton({className, onClick, isEnabled}) {
+import React from "react";
+import clsx from "clsx";
+import { translate } from "@docusaurus/Translate";
+import IconWordWrap from "@theme/Icon/WordWrap";
+import styles from "./styles.module.css";
+export default function WordWrapButton({ className, onClick, isEnabled }) {
const title = translate({
- id: 'theme.CodeBlock.wordWrapToggle',
- message: 'Toggle word wrap',
+ id: "theme.CodeBlock.wordWrapToggle",
+ message: "Toggle word wrap",
description:
- 'The title attribute for toggle word wrapping button of code block lines',
+ "The title attribute for toggle word wrapping button of code block lines",
});
return (
+ title={title}
+ >
);
diff --git a/src/theme/CodeBlock/index.js b/src/theme/CodeBlock/index.js
index 8cb51098edd..f6d24842a6d 100644
--- a/src/theme/CodeBlock/index.js
+++ b/src/theme/CodeBlock/index.js
@@ -1,7 +1,7 @@
-import React, {isValidElement} from 'react';
-import useIsBrowser from '@docusaurus/useIsBrowser';
-import ElementContent from '@theme/CodeBlock/Content/Element';
-import StringContent from '@theme/CodeBlock/Content/String';
+import React, { isValidElement } from "react";
+import useIsBrowser from "@docusaurus/useIsBrowser";
+import ElementContent from "@theme/CodeBlock/Content/Element";
+import StringContent from "@theme/CodeBlock/Content/String";
/**
* Best attempt to make the children a plain string so it is copyable. If there
* are react elements, we will not be able to copy the content, and it will
@@ -13,17 +13,17 @@ function maybeStringifyChildren(children) {
return children;
}
// The children is now guaranteed to be one/more plain strings
- return Array.isArray(children) ? children.join('') : children;
+ return Array.isArray(children) ? children.join("") : children;
}
function parseOutput(content) {
const codeRegex = /([\s\S]*?)<\/output>/i;
- const code = content.replace(codeRegex, '').trim();
+ const code = content.replace(codeRegex, "").trim();
const output = content.match(codeRegex)?.[1].trim();
return { code, output };
}
-export default function CodeBlock({children: rawChildren, ...props}) {
+export default function CodeBlock({ children: rawChildren, ...props }) {
// The Prism theme on SSR is always the default theme but the site theme can
// be in a different mode. React hydration doesn't update DOM styles that come
// from SSR. Hence force a re-render after mounting to apply the current
@@ -35,7 +35,7 @@ export default function CodeBlock({children: rawChildren, ...props}) {
let code = children;
let output = null;
- if (typeof children === 'string') {
+ if (typeof children === "string") {
CodeBlockComp = StringContent;
const parsed = parseOutput(children);
code = parsed.code;
@@ -44,7 +44,6 @@ export default function CodeBlock({children: rawChildren, ...props}) {
CodeBlockComp = ElementContent;
}
-
return (
{children}
diff --git a/src/theme/DocCardList/index.js b/src/theme/DocCardList/index.js
index 7c0a761f5d6..92f2c508867 100644
--- a/src/theme/DocCardList/index.js
+++ b/src/theme/DocCardList/index.js
@@ -1,31 +1,38 @@
-import React from 'react';
+import React from "react";
import {
useCurrentSidebarCategory,
filterDocCardListItems,
-} from '@docusaurus/theme-common';
-import DocCard from '@theme/DocCard';
-import styles from './styles.module.scss';
-import {useDoc} from "@docusaurus/theme-common/internal";
-import { useDocById } from '@docusaurus/theme-common/internal';
-import usePluginData from '@docusaurus/useGlobalData';
-
+} from "@docusaurus/theme-common";
+import DocCard from "@theme/DocCard";
+import styles from "./styles.module.scss";
+import { useDoc } from "@docusaurus/theme-common/internal";
+import { useDocById } from "@docusaurus/theme-common/internal";
+import usePluginData from "@docusaurus/useGlobalData";
function filterItems(items) {
let filteredItems;
- if (Array.isArray(items) && items.length > 0 && typeof items[0] === 'string') {
+ if (
+ Array.isArray(items) &&
+ items.length > 0 &&
+ typeof items[0] === "string"
+ ) {
const matchingDocs = items.map((item) => {
return useDocById(item);
});
- const {metadata} = useDoc();
+ const { metadata } = useDoc();
const activeVersion = metadata.version;
- const pluginData = usePluginData('docusaurus-plugin-content-docs')['docusaurus-plugin-content-docs'];
+ const pluginData = usePluginData("docusaurus-plugin-content-docs")[
+ "docusaurus-plugin-content-docs"
+ ];
const versions = pluginData.default.versions;
- const activeVersionData = versions.find((version) => version.name === activeVersion);
+ const activeVersionData = versions.find(
+ (version) => version.name === activeVersion,
+ );
const matchingPaths = activeVersionData.docs.filter((doc) => {
- return matchingDocs.find((match) => match.id === doc.id);
+ return matchingDocs.find((match) => match.id === doc.id);
});
filteredItems = matchingDocs.map((doc) => {
@@ -36,7 +43,7 @@ function filterItems(items) {
label: doc.title,
type: "link",
unlisted: false,
- }
+ };
});
} else if (!items) {
const category = useCurrentSidebarCategory();
@@ -50,9 +57,8 @@ function filterItems(items) {
return filteredItems;
}
-
export default function DocCardList(props) {
- const {items, children} = props;
+ const { items, children } = props;
if (children) {
return ;
diff --git a/src/theme/DocCardList/styles.module.scss b/src/theme/DocCardList/styles.module.scss
index ac1e42fca47..b9899cd0256 100644
--- a/src/theme/DocCardList/styles.module.scss
+++ b/src/theme/DocCardList/styles.module.scss
@@ -1,4 +1,4 @@
-@import '../../css/_mixins.scss';
+@import "../../css/_mixins.scss";
.section {
display: flex;
@@ -14,18 +14,26 @@
background: var(--custom-surface-color);
border-radius: 8px;
border: 1px solid var(--ifm-toc-border-color);
- transition: border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default);
+ transition: border-color var(--ifm-transition-fast)
+ var(--ifm-transition-timing-default);
box-shadow: var(--ifm-alert-shadow);
padding: 16px;
- h1, h2, h3, h4, h5, h6 {
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
margin: 0;
padding: 0;
font-size: var(--ifm-h3-font-size);
color: var(--ifm-color-primary);
}
- span, p, div {
+ span,
+ p,
+ div {
font-size: var(--ifm-font-size-base);
color: var(--ifm-color-content-secondary);
margin: 16px 0 0;
@@ -42,7 +50,6 @@
}
}
-
//.section {
// display: flex;
// flex-wrap: wrap; // Allow items to wrap on smaller screens
@@ -73,4 +80,4 @@
// &__content {
// //color: $color-card-text;
// }
-//}
\ No newline at end of file
+//}
diff --git a/src/theme/DocItem/TOC/Desktop/index.jsx b/src/theme/DocItem/TOC/Desktop/index.jsx
index 80503082ec7..91d5265e5ee 100644
--- a/src/theme/DocItem/TOC/Desktop/index.jsx
+++ b/src/theme/DocItem/TOC/Desktop/index.jsx
@@ -1,92 +1,147 @@
-import React from 'react';
-import {ThemeClassNames} from '@docusaurus/theme-common';
-import {useDoc} from '@docusaurus/theme-common/internal';
-import TOC from '@theme/TOC';
-import styles from './styles.module.scss';
-
+import React from "react";
+import { ThemeClassNames } from "@docusaurus/theme-common";
+import { useDoc } from "@docusaurus/theme-common/internal";
+import TOC from "@theme/TOC";
+import styles from "./styles.module.scss";
const SlackIcon = () => (
-
-
-
-
-
-
+
+
+
+
+
+
);
const SupportIcon = () => (
-
-
-
-)
+
+
+
+);
const GithubIcon = () => (
-
-
-
+
+
+
);
const EditIcon = () => (
-
-
-
+
+
+
);
+export default function DocItemTOCDesktop({ ...props }) {
+ const { toc, frontMatter, metadata } = useDoc();
+ const editUrl = frontMatter.custom_edit_url
+ ? frontMatter.custom_edit_url
+ : metadata.editUrl;
-export default function DocItemTOCDesktop({...props}) {
- const {toc, frontMatter, metadata} = useDoc();
- const editUrl = frontMatter.custom_edit_url ? frontMatter.custom_edit_url : metadata.editUrl;
-
- const issuesBaseURL = 'https://github.com/neuralmagic/';
- const issueLinks = [
- { name: 'DeepSparse', path: 'deepsparse/issues' },
- { name: 'SparseML', path: 'sparseml/issues' },
- { name: 'SparseZoo', path: 'sparsezoo/issues' },
- ];
+ const issuesBaseURL = "https://github.com/neuralmagic/";
+ const issueLinks = [
+ { name: "DeepSparse", path: "deepsparse/issues" },
+ { name: "SparseML", path: "sparseml/issues" },
+ { name: "SparseZoo", path: "sparsezoo/issues" },
+ ];
+ return (
+
+
+
Content
+
+
- return (
-
-
-
Content
-
-
-
-
+
-
+
-
+
+
+ );
}
diff --git a/src/theme/DocItem/TOC/Desktop/styles.module.scss b/src/theme/DocItem/TOC/Desktop/styles.module.scss
index 84f6a108b1b..c307f928cf3 100644
--- a/src/theme/DocItem/TOC/Desktop/styles.module.scss
+++ b/src/theme/DocItem/TOC/Desktop/styles.module.scss
@@ -21,11 +21,13 @@
padding-left: 0;
}
-.link, .linkListTitle {
+.link,
+.linkListTitle {
color: var(--ifm-toc-link-color);
display: flex;
text-decoration: var(--ifm-link-decoration);
- transition: color var(--ifm-transition-fast) var(--ifm-transition-timing-default);
+ transition: color var(--ifm-transition-fast)
+ var(--ifm-transition-timing-default);
font-size: 1rem;
align-items: center;
margin-bottom: 4px;
@@ -35,4 +37,4 @@
margin-right: 0.5rem;
width: 20px;
height: 20px;
-}
\ No newline at end of file
+}
diff --git a/src/theme/DocRoot/Layout/Main/index.jsx b/src/theme/DocRoot/Layout/Main/index.jsx
index cef2081c523..40a0729f8d6 100644
--- a/src/theme/DocRoot/Layout/Main/index.jsx
+++ b/src/theme/DocRoot/Layout/Main/index.jsx
@@ -1,22 +1,27 @@
-import React from 'react';
-import clsx from 'clsx';
-import {useDocsSidebar} from '@docusaurus/theme-common/internal';
-import styles from './styles.module.scss';
+import React from "react";
+import clsx from "clsx";
+import { useDocsSidebar } from "@docusaurus/theme-common/internal";
+import styles from "./styles.module.scss";
-export default function DocRootLayoutMain({hiddenSidebarContainer, children}) {
+export default function DocRootLayoutMain({
+ hiddenSidebarContainer,
+ children,
+}) {
const sidebar = useDocsSidebar();
return (
+ )}
+ >
+ )}
+ >
{children}
diff --git a/src/theme/DocRoot/Layout/Main/styles.module.scss b/src/theme/DocRoot/Layout/Main/styles.module.scss
index 0dee0decbf9..5f4cd03c21c 100644
--- a/src/theme/DocRoot/Layout/Main/styles.module.scss
+++ b/src/theme/DocRoot/Layout/Main/styles.module.scss
@@ -1,4 +1,4 @@
-@import '../../../../../src/css/_screen-layouts';
+@import "../../../../../src/css/_screen-layouts";
.docMainContainer {
display: flex;
@@ -21,8 +21,6 @@
}
.docItemWrapperEnhanced {
- max-width: calc(
- var(--body-width)
- ) !important;
+ max-width: calc(var(--body-width)) !important;
}
}
diff --git a/src/theme/DocRoot/Layout/Sidebar/ExpandButton/index.js b/src/theme/DocRoot/Layout/Sidebar/ExpandButton/index.js
index c3a354687a6..8a47010763f 100644
--- a/src/theme/DocRoot/Layout/Sidebar/ExpandButton/index.js
+++ b/src/theme/DocRoot/Layout/Sidebar/ExpandButton/index.js
@@ -1,27 +1,28 @@
-import React from 'react';
-import {translate} from '@docusaurus/Translate';
-import IconArrow from '@theme/Icon/Arrow';
-import styles from './styles.module.css';
-export default function DocRootLayoutSidebarExpandButton({toggleSidebar}) {
+import React from "react";
+import { translate } from "@docusaurus/Translate";
+import IconArrow from "@theme/Icon/Arrow";
+import styles from "./styles.module.css";
+export default function DocRootLayoutSidebarExpandButton({ toggleSidebar }) {
return (
+ onClick={toggleSidebar}
+ >
);
diff --git a/src/theme/DocRoot/Layout/Sidebar/ExpandButton/styles.module.css b/src/theme/DocRoot/Layout/Sidebar/ExpandButton/styles.module.css
index f4cd944d83c..cc480551b21 100644
--- a/src/theme/DocRoot/Layout/Sidebar/ExpandButton/styles.module.css
+++ b/src/theme/DocRoot/Layout/Sidebar/ExpandButton/styles.module.css
@@ -21,7 +21,7 @@
transform: rotate(0);
}
- [dir='rtl'] .expandButtonIcon {
+ [dir="rtl"] .expandButtonIcon {
transform: rotate(180deg);
}
}
diff --git a/src/theme/DocRoot/Layout/Sidebar/index.jsx b/src/theme/DocRoot/Layout/Sidebar/index.jsx
index 439b96769e7..a0b4617be44 100644
--- a/src/theme/DocRoot/Layout/Sidebar/index.jsx
+++ b/src/theme/DocRoot/Layout/Sidebar/index.jsx
@@ -1,16 +1,19 @@
-import React, {useState, useCallback} from 'react';
-import clsx from 'clsx';
-import {prefersReducedMotion, ThemeClassNames} from '@docusaurus/theme-common';
-import {useDocsSidebar} from '@docusaurus/theme-common/internal';
-import {useLocation} from '@docusaurus/router';
-import DocSidebar from '@theme/DocSidebar';
-import ExpandButton from '@theme/DocRoot/Layout/Sidebar/ExpandButton';
-import styles from './styles.module.scss';
+import React, { useState, useCallback } from "react";
+import clsx from "clsx";
+import {
+ prefersReducedMotion,
+ ThemeClassNames,
+} from "@docusaurus/theme-common";
+import { useDocsSidebar } from "@docusaurus/theme-common/internal";
+import { useLocation } from "@docusaurus/router";
+import DocSidebar from "@theme/DocSidebar";
+import ExpandButton from "@theme/DocRoot/Layout/Sidebar/ExpandButton";
+import styles from "./styles.module.scss";
-function ResetOnSidebarChange({children}) {
+function ResetOnSidebarChange({ children }) {
const sidebar = useDocsSidebar();
return (
-
+
{children}
);
@@ -21,7 +24,7 @@ export default function DocRootLayoutSidebar({
hiddenSidebarContainer,
setHiddenSidebarContainer,
}) {
- const {pathname} = useLocation();
+ const { pathname } = useLocation();
const [hiddenSidebar, setHiddenSidebar] = useState(false);
const toggleSidebar = useCallback(() => {
if (hiddenSidebar) {
@@ -48,13 +51,15 @@ export default function DocRootLayoutSidebar({
if (hiddenSidebarContainer) {
setHiddenSidebar(true);
}
- }}>
+ }}
+ >
+ )}
+ >
+ onClick={onClick}
+ >
);
diff --git a/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css b/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css
index df46519f224..5a80bcf88c4 100644
--- a/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css
+++ b/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css
@@ -3,7 +3,7 @@
--docusaurus-collapse-button-bg-hover: rgb(0 0 0 / 10%);
}
-[data-theme='dark']:root {
+[data-theme="dark"]:root {
--docusaurus-collapse-button-bg: rgb(255 255 255 / 5%);
--docusaurus-collapse-button-bg-hover: rgb(255 255 255 / 10%);
}
@@ -24,7 +24,7 @@
margin-top: 4px;
}
- [dir='rtl'] .collapseSidebarButtonIcon {
+ [dir="rtl"] .collapseSidebarButtonIcon {
transform: rotate(0);
}
diff --git a/src/theme/DocSidebar/Desktop/Content/index.js b/src/theme/DocSidebar/Desktop/Content/index.js
index c88b0db25ac..1c8f93ba5be 100644
--- a/src/theme/DocSidebar/Desktop/Content/index.js
+++ b/src/theme/DocSidebar/Desktop/Content/index.js
@@ -1,18 +1,18 @@
-import React, {useState} from 'react';
-import clsx from 'clsx';
-import {ThemeClassNames} from '@docusaurus/theme-common';
+import React, { useState } from "react";
+import clsx from "clsx";
+import { ThemeClassNames } from "@docusaurus/theme-common";
import {
useAnnouncementBar,
useScrollPosition,
-} from '@docusaurus/theme-common/internal';
-import {translate} from '@docusaurus/Translate';
-import DocSidebarItems from '@theme/DocSidebarItems';
-import styles from './styles.module.css';
+} from "@docusaurus/theme-common/internal";
+import { translate } from "@docusaurus/Translate";
+import DocSidebarItems from "@theme/DocSidebarItems";
+import styles from "./styles.module.css";
function useShowAnnouncementBar() {
- const {isActive} = useAnnouncementBar();
+ const { isActive } = useAnnouncementBar();
const [showAnnouncementBar, setShowAnnouncementBar] = useState(isActive);
useScrollPosition(
- ({scrollY}) => {
+ ({ scrollY }) => {
if (isActive) {
setShowAnnouncementBar(scrollY === 0);
}
@@ -21,22 +21,23 @@ function useShowAnnouncementBar() {
);
return isActive && showAnnouncementBar;
}
-export default function DocSidebarDesktopContent({path, sidebar, className}) {
+export default function DocSidebarDesktopContent({ path, sidebar, className }) {
const showAnnouncementBar = useShowAnnouncementBar();
return (
-
diff --git a/src/theme/DocSidebar/Desktop/index.js b/src/theme/DocSidebar/Desktop/index.js
index 07f1464f8ff..1abe0cd99e0 100644
--- a/src/theme/DocSidebar/Desktop/index.js
+++ b/src/theme/DocSidebar/Desktop/index.js
@@ -1,15 +1,15 @@
-import React from 'react';
-import clsx from 'clsx';
-import {useThemeConfig} from '@docusaurus/theme-common';
-import Logo from '@theme/Logo';
-import CollapseButton from '@theme/DocSidebar/Desktop/CollapseButton';
-import Content from '@theme/DocSidebar/Desktop/Content';
-import styles from './styles.module.css';
-function DocSidebarDesktop({path, sidebar, onCollapse, isHidden}) {
+import React from "react";
+import clsx from "clsx";
+import { useThemeConfig } from "@docusaurus/theme-common";
+import Logo from "@theme/Logo";
+import CollapseButton from "@theme/DocSidebar/Desktop/CollapseButton";
+import Content from "@theme/DocSidebar/Desktop/Content";
+import styles from "./styles.module.css";
+function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }) {
const {
- navbar: {hideOnScroll},
+ navbar: { hideOnScroll },
docs: {
- sidebar: {hideable},
+ sidebar: { hideable },
},
} = useThemeConfig();
return (
@@ -18,7 +18,8 @@ function DocSidebarDesktop({path, sidebar, onCollapse, isHidden}) {
styles.sidebar,
hideOnScroll && styles.sidebarWithHideableNavbar,
isHidden && styles.sidebarHidden,
- )}>
+ )}
+ >
{hideOnScroll && }
{hideable && }
diff --git a/src/theme/DocSidebar/Mobile/index.js b/src/theme/DocSidebar/Mobile/index.js
index 9fc6a832be6..751e8c0c2af 100644
--- a/src/theme/DocSidebar/Mobile/index.js
+++ b/src/theme/DocSidebar/Mobile/index.js
@@ -1,25 +1,25 @@
-import React from 'react';
-import clsx from 'clsx';
+import React from "react";
+import clsx from "clsx";
import {
NavbarSecondaryMenuFiller,
ThemeClassNames,
-} from '@docusaurus/theme-common';
-import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
-import DocSidebarItems from '@theme/DocSidebarItems';
+} from "@docusaurus/theme-common";
+import { useNavbarMobileSidebar } from "@docusaurus/theme-common/internal";
+import DocSidebarItems from "@theme/DocSidebarItems";
// eslint-disable-next-line react/function-component-definition
-const DocSidebarMobileSecondaryMenu = ({sidebar, path}) => {
+const DocSidebarMobileSecondaryMenu = ({ sidebar, path }) => {
const mobileSidebar = useNavbarMobileSidebar();
return (
-
+
{
// Mobile sidebar should only be closed if the category has a link
- if (item.type === 'category' && item.href) {
+ if (item.type === "category" && item.href) {
mobileSidebar.toggle();
}
- if (item.type === 'link') {
+ if (item.type === "link") {
mobileSidebar.toggle();
}
}}
diff --git a/src/theme/DocSidebar/index.js b/src/theme/DocSidebar/index.js
index d0f4e7e759d..1d1e3379f51 100644
--- a/src/theme/DocSidebar/index.js
+++ b/src/theme/DocSidebar/index.js
@@ -1,14 +1,14 @@
-import React from 'react';
-import {useWindowSize} from '@docusaurus/theme-common';
-import DocSidebarDesktop from '@theme/DocSidebar/Desktop';
-import DocSidebarMobile from '@theme/DocSidebar/Mobile';
+import React from "react";
+import { useWindowSize } from "@docusaurus/theme-common";
+import DocSidebarDesktop from "@theme/DocSidebar/Desktop";
+import DocSidebarMobile from "@theme/DocSidebar/Mobile";
export default function DocSidebar(props) {
const windowSize = useWindowSize();
// Desktop sidebar visible on hydration: need SSR rendering
const shouldRenderSidebarDesktop =
- windowSize === 'desktop' || windowSize === 'ssr';
+ windowSize === "desktop" || windowSize === "ssr";
// Mobile sidebar not visible on hydration: can avoid SSR rendering
- const shouldRenderSidebarMobile = windowSize === 'mobile';
+ const shouldRenderSidebarMobile = windowSize === "mobile";
return (
<>
{shouldRenderSidebarDesktop && }
diff --git a/src/theme/DocVersionBanner/index.js b/src/theme/DocVersionBanner/index.js
index fdf053465fb..2a64df9164e 100644
--- a/src/theme/DocVersionBanner/index.js
+++ b/src/theme/DocVersionBanner/index.js
@@ -1,19 +1,19 @@
-import React from 'react';
-import clsx from 'clsx';
-import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
-import Link from '@docusaurus/Link';
-import Translate from '@docusaurus/Translate';
+import React from "react";
+import clsx from "clsx";
+import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
+import Link from "@docusaurus/Link";
+import Translate from "@docusaurus/Translate";
import {
useActivePlugin,
useDocVersionSuggestions,
-} from '@docusaurus/plugin-content-docs/client';
-import {ThemeClassNames} from '@docusaurus/theme-common';
+} from "@docusaurus/plugin-content-docs/client";
+import { ThemeClassNames } from "@docusaurus/theme-common";
import {
useDocsPreferredVersion,
useDocsVersion,
-} from '@docusaurus/theme-common/internal';
+} from "@docusaurus/theme-common/internal";
-function UnreleasedVersionLabel({siteTitle, versionMetadata}) {
+function UnreleasedVersionLabel({ siteTitle, versionMetadata }) {
return (
{versionMetadata.label},
- }}>
- {
- 'This is unreleased documentation for the {versionLabel} version.'
- }
+ }}
+ >
+ {"This is unreleased documentation for the {versionLabel} version."}
);
}
-function UnmaintainedVersionLabel({siteTitle, versionMetadata}) {
+function UnmaintainedVersionLabel({ siteTitle, versionMetadata }) {
return (
{versionMetadata.label},
- }}>
+ }}
+ >
{
- 'This is documentation for the {versionLabel} version, which is no longer actively maintained.'
+ "This is documentation for the {versionLabel} version, which is no longer actively maintained."
}
);
@@ -52,7 +52,7 @@ function BannerLabel(props) {
BannerLabelComponents[props.versionMetadata.banner];
return ;
}
-function LatestVersionSuggestionLabel({versionLabel, to, onClick}) {
+function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) {
return (
+ description="The label used for the latest version suggestion link label"
+ >
current version
),
- }}>
+ }}
+ >
{
- 'For the latest released documentation, see the {latestVersionLink} ({versionLabel}).'
+ "For the latest released documentation, see the {latestVersionLink} ({versionLabel})."
}
);
}
-function DocVersionBannerEnabled({className, versionMetadata}) {
+function DocVersionBannerEnabled({ className, versionMetadata }) {
const {
- siteConfig: {title: siteTitle},
+ siteConfig: { title: siteTitle },
} = useDocusaurusContext();
- const {pluginId} = useActivePlugin({failfast: true});
+ const { pluginId } = useActivePlugin({ failfast: true });
const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId);
- const {savePreferredVersionName} = useDocsPreferredVersion(pluginId);
- const {latestDocSuggestion, latestVersionSuggestion} =
+ const { savePreferredVersionName } = useDocsPreferredVersion(pluginId);
+ const { latestDocSuggestion, latestVersionSuggestion } =
useDocVersionSuggestions(pluginId);
// Try to link to same doc in latest version (not always possible), falling
// back to main doc of latest version
@@ -96,9 +98,10 @@ function DocVersionBannerEnabled({className, versionMetadata}) {
className={clsx(
className,
ThemeClassNames.docs.docVersionBanner,
- 'alert alert--warning margin-bottom--md',
+ "alert alert--warning margin-bottom--md",
)}
- role="alert">
+ role="alert"
+ >
@@ -112,7 +115,7 @@ function DocVersionBannerEnabled({className, versionMetadata}) {
);
}
-export default function DocVersionBanner({className}) {
+export default function DocVersionBanner({ className }) {
const versionMetadata = useDocsVersion();
if (versionMetadata.banner) {
return (
diff --git a/src/theme/MDXComponents/index.js b/src/theme/MDXComponents/index.js
index fde830cf3f1..aea3bc3db1d 100644
--- a/src/theme/MDXComponents/index.js
+++ b/src/theme/MDXComponents/index.js
@@ -1,25 +1,37 @@
-import React from 'react';
-import MDXComponents from '@theme-original/MDXComponents';
+import React from "react";
+import MDXComponents from "@theme-original/MDXComponents";
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-import DocCardList from '@theme/DocCardList';
+import Tabs from "@theme/Tabs";
+import TabItem from "@theme/TabItem";
+import DocCardList from "@theme/DocCardList";
import GithubReleases from "../../components/github-releases";
import VersionInjector from "../../components/version-injector";
import GlossaryTable from "../../components/glossary/table";
import Tooltip from "../../components/glossary/tool-tip";
+// Graphs
+import NeuralMagicTradeoffTriangle from "../../components/graphs/tradeoff-triangle";
+import NeuralMagicBar from "../../components/graphs/bar";
+import NeuralMagicNeuralNet from "../../components/graphs/neuralnet";
+import NeuralMagicLineChart from "../../components/graphs/line";
+
export default {
// Re-use the default mapping
...MDXComponents,
// New mappings
- DocCardList,
+ DocCardList,
GithubReleases,
VersionInjector,
Tabs,
TabItem,
GlossaryTable,
Tooltip,
-};
\ No newline at end of file
+
+ // Graphs
+ NeuralMagicTradeoffTriangle,
+ NeuralMagicBar,
+ NeuralMagicNeuralNet,
+ NeuralMagicLineChart,
+};
diff --git a/static/fonts/SpeziaMonoWeb-Medium.woff b/static/fonts/SpeziaMonoWeb-Medium.woff
new file mode 100644
index 00000000000..be70734822d
Binary files /dev/null and b/static/fonts/SpeziaMonoWeb-Medium.woff differ
diff --git a/static/fonts/SpeziaWeb-Medium.woff b/static/fonts/SpeziaWeb-Medium.woff
new file mode 100644
index 00000000000..3547ca9133e
Binary files /dev/null and b/static/fonts/SpeziaWeb-Medium.woff differ
diff --git a/static/fonts/SpeziaWeb-Regular.woff b/static/fonts/SpeziaWeb-Regular.woff
new file mode 100644
index 00000000000..df209bc4a52
Binary files /dev/null and b/static/fonts/SpeziaWeb-Regular.woff differ