@skillpet/circuit
Version:
Circuit diagram library — render electrical schematics from JSON, with interactive SVG, themes, and Vue/React components
1,216 lines (1,215 loc) • 1.13 MB
JavaScript
"use strict";
var Circuit = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// node_modules/katex/dist/katex.mjs
var katex_exports = {};
__export(katex_exports, {
ParseError: () => ParseError,
SETTINGS_SCHEMA: () => SETTINGS_SCHEMA,
__defineFunction: () => defineFunction,
__defineMacro: () => defineMacro,
__defineSymbol: () => defineSymbol,
__domTree: () => __domTree,
__parse: () => generateParseTree,
__renderToDomTree: () => renderToDomTree,
__renderToHTMLTree: () => renderToHTMLTree,
__setFontMetrics: () => setFontMetrics,
default: () => katex,
render: () => render,
renderToString: () => renderToString,
version: () => version
});
function getDefaultValue(schema) {
if ("default" in schema) {
return schema.default;
}
var type = schema.type;
var defaultType = Array.isArray(type) ? type[0] : type;
if (typeof defaultType !== "string") {
return defaultType.enum[0];
}
switch (defaultType) {
case "boolean":
return false;
case "string":
return "";
case "number":
return 0;
case "object":
return {};
}
}
function scriptFromCodepoint(codepoint) {
for (var i = 0; i < scriptData.length; i++) {
var script = scriptData[i];
for (var _i = 0; _i < script.blocks.length; _i++) {
var block = script.blocks[_i];
if (codepoint >= block[0] && codepoint <= block[1]) {
return script.name;
}
}
}
return null;
}
function supportedCodepoint(codepoint) {
for (var i = 0; i < allBlocks.length; i += 2) {
if (codepoint >= allBlocks[i] && codepoint <= allBlocks[i + 1]) {
return true;
}
}
return false;
}
function assertSymbolDomNode(group) {
if (group instanceof SymbolNode) {
return group;
} else {
throw new Error("Expected symbolNode but got " + String(group) + ".");
}
}
function assertSpan(group) {
if (group instanceof Span) {
return group;
} else {
throw new Error("Expected span<HtmlDomNode> but got " + String(group) + ".");
}
}
function setFontMetrics(fontName, metrics) {
fontMetricsData[fontName] = metrics;
}
function getCharacterMetrics(character, font, mode) {
if (!fontMetricsData[font]) {
throw new Error("Font metrics not found for font: " + font + ".");
}
var ch = character.charCodeAt(0);
var metrics = fontMetricsData[font][ch];
if (!metrics && character[0] in extraCharacterMap) {
ch = extraCharacterMap[character[0]].charCodeAt(0);
metrics = fontMetricsData[font][ch];
}
if (!metrics && mode === "text") {
if (supportedCodepoint(ch)) {
metrics = fontMetricsData[font][77];
}
}
if (metrics) {
return {
depth: metrics[0],
height: metrics[1],
italic: metrics[2],
skew: metrics[3],
width: metrics[4]
};
}
}
function getGlobalMetrics(size) {
var sizeIndex;
if (size >= 5) {
sizeIndex = 0;
} else if (size >= 3) {
sizeIndex = 1;
} else {
sizeIndex = 2;
}
if (!fontMetricsBySizeIndex[sizeIndex]) {
var metrics = fontMetricsBySizeIndex[sizeIndex] = {
cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18
};
for (var key in sigmasAndXis) {
if (sigmasAndXis.hasOwnProperty(key)) {
metrics[key] = sigmasAndXis[key][sizeIndex];
}
}
}
return fontMetricsBySizeIndex[sizeIndex];
}
function defineSymbol(mode, font, group, replace, name, acceptUnicodeChar) {
symbols[mode][name] = {
font,
group,
replace
};
if (acceptUnicodeChar && replace) {
symbols[mode][replace] = symbols[mode][name];
}
}
function defineFunction(_ref) {
var {
type,
names,
props,
handler,
htmlBuilder: htmlBuilder3,
mathmlBuilder: mathmlBuilder3
} = _ref;
var data = {
type,
numArgs: props.numArgs,
argTypes: props.argTypes,
allowedInArgument: !!props.allowedInArgument,
allowedInText: !!props.allowedInText,
allowedInMath: props.allowedInMath === void 0 ? true : props.allowedInMath,
numOptionalArgs: props.numOptionalArgs || 0,
infix: !!props.infix,
primitive: !!props.primitive,
handler
};
for (var i = 0; i < names.length; ++i) {
_functions[names[i]] = data;
}
if (type) {
if (htmlBuilder3) {
_htmlGroupBuilders[type] = htmlBuilder3;
}
if (mathmlBuilder3) {
_mathmlGroupBuilders[type] = mathmlBuilder3;
}
}
}
function defineFunctionBuilders(_ref2) {
var {
type,
htmlBuilder: htmlBuilder3,
mathmlBuilder: mathmlBuilder3
} = _ref2;
defineFunction({
type,
names: [],
props: {
numArgs: 0
},
handler() {
throw new Error("Should never be called.");
},
htmlBuilder: htmlBuilder3,
mathmlBuilder: mathmlBuilder3
});
}
function buildHTMLUnbreakable(children, options) {
var body = makeSpan(["base"], children, options);
var strut = makeSpan(["strut"]);
strut.style.height = makeEm(body.height + body.depth);
if (body.depth) {
strut.style.verticalAlign = makeEm(-body.depth);
}
body.children.unshift(strut);
return body;
}
function buildHTML(tree, options) {
var tag = null;
if (tree.length === 1 && tree[0].type === "tag") {
tag = tree[0].tag;
tree = tree[0].body;
}
var expression = buildExpression$1(tree, options, "root");
var eqnNum;
if (expression.length === 2 && expression[1].hasClass("tag")) {
eqnNum = expression.pop();
}
var children = [];
var parts = [];
for (var i = 0; i < expression.length; i++) {
parts.push(expression[i]);
if (expression[i].hasClass("mbin") || expression[i].hasClass("mrel") || expression[i].hasClass("allowbreak")) {
var nobreak = false;
while (i < expression.length - 1 && expression[i + 1].hasClass("mspace") && !expression[i + 1].hasClass("newline")) {
i++;
parts.push(expression[i]);
if (expression[i].hasClass("nobreak")) {
nobreak = true;
}
}
if (!nobreak) {
children.push(buildHTMLUnbreakable(parts, options));
parts = [];
}
} else if (expression[i].hasClass("newline")) {
parts.pop();
if (parts.length > 0) {
children.push(buildHTMLUnbreakable(parts, options));
parts = [];
}
children.push(expression[i]);
}
}
if (parts.length > 0) {
children.push(buildHTMLUnbreakable(parts, options));
}
var tagChild;
if (tag) {
tagChild = buildHTMLUnbreakable(buildExpression$1(tag, options, true), options);
tagChild.classes = ["tag"];
children.push(tagChild);
} else if (eqnNum) {
children.push(eqnNum);
}
var htmlNode = makeSpan(["katex-html"], children);
htmlNode.setAttribute("aria-hidden", "true");
if (tagChild) {
var strut = tagChild.children[0];
strut.style.height = makeEm(htmlNode.height + htmlNode.depth);
if (htmlNode.depth) {
strut.style.verticalAlign = makeEm(-htmlNode.depth);
}
}
return htmlNode;
}
function newDocumentFragment(children) {
return new DocumentFragment(children);
}
function isNumberPunctuation(group) {
if (!group) {
return false;
}
if (group.type === "mi" && group.children.length === 1) {
var child = group.children[0];
return child instanceof TextNode && child.text === ".";
} else if (group.type === "mo" && group.children.length === 1 && group.getAttribute("separator") === "true" && group.getAttribute("lspace") === "0em" && group.getAttribute("rspace") === "0em") {
var _child = group.children[0];
return _child instanceof TextNode && _child.text === ",";
} else {
return false;
}
}
function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly) {
var expression = buildExpression2(tree, options);
var wrapper;
if (expression.length === 1 && expression[0] instanceof MathNode && rowLikeTypes.has(expression[0].type)) {
wrapper = expression[0];
} else {
wrapper = new MathNode("mrow", expression);
}
var annotation = new MathNode("annotation", [new TextNode(texExpression)]);
annotation.setAttribute("encoding", "application/x-tex");
var semantics = new MathNode("semantics", [wrapper, annotation]);
var math2 = new MathNode("math", [semantics]);
math2.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
if (isDisplayMode) {
math2.setAttribute("display", "block");
}
var wrapperClass = forMathmlOnly ? "katex" : "katex-mathml";
return makeSpan([wrapperClass], [math2]);
}
function assertNodeType(node, type) {
if (!node || node.type !== type) {
throw new Error("Expected node of type " + type + ", but got " + (node ? "node of type " + node.type : String(node)));
}
return node;
}
function assertSymbolNodeType(node) {
var typedNode = checkSymbolNodeType(node);
if (!typedNode) {
throw new Error("Expected node of symbol group type, but got " + (node ? "node of type " + node.type : String(node)));
}
return typedNode;
}
function checkSymbolNodeType(node) {
if (node && (node.type === "atom" || NON_ATOMS.hasOwnProperty(node.type))) {
return node;
}
return null;
}
function htmlBuilder$9(group, options) {
var elements = buildExpression$1(group.body, options, true);
return makeSpan([group.mclass], elements, options);
}
function mathmlBuilder$8(group, options) {
var node;
var inner2 = buildExpression2(group.body, options);
if (group.mclass === "minner") {
node = new MathNode("mpadded", inner2);
} else if (group.mclass === "mord") {
if (group.isCharacterBox) {
node = inner2[0];
node.type = "mi";
} else {
node = new MathNode("mi", inner2);
}
} else {
if (group.isCharacterBox) {
node = inner2[0];
node.type = "mo";
} else {
node = new MathNode("mo", inner2);
}
if (group.mclass === "mbin") {
node.attributes.lspace = "0.22em";
node.attributes.rspace = "0.22em";
} else if (group.mclass === "mpunct") {
node.attributes.lspace = "0em";
node.attributes.rspace = "0.17em";
} else if (group.mclass === "mopen" || group.mclass === "mclose") {
node.attributes.lspace = "0em";
node.attributes.rspace = "0em";
} else if (group.mclass === "minner") {
node.attributes.lspace = "0.0556em";
node.attributes.width = "+0.1111em";
}
}
return node;
}
function cdArrow(arrowChar, labels, parser) {
var funcName = cdArrowFunctionName[arrowChar];
switch (funcName) {
case "\\\\cdrightarrow":
case "\\\\cdleftarrow":
return parser.callFunction(funcName, [labels[0]], [labels[1]]);
case "\\uparrow":
case "\\downarrow": {
var leftLabel = parser.callFunction("\\\\cdleft", [labels[0]], []);
var bareArrow = {
type: "atom",
text: funcName,
mode: "math",
family: "rel"
};
var sizedArrow = parser.callFunction("\\Big", [bareArrow], []);
var rightLabel = parser.callFunction("\\\\cdright", [labels[1]], []);
var arrowGroup = {
type: "ordgroup",
mode: "math",
body: [leftLabel, sizedArrow, rightLabel]
};
return parser.callFunction("\\\\cdparent", [arrowGroup], []);
}
case "\\\\cdlongequal":
return parser.callFunction("\\\\cdlongequal", [], []);
case "\\Vert": {
var arrow = {
type: "textord",
text: "\\Vert",
mode: "math"
};
return parser.callFunction("\\Big", [arrow], []);
}
default:
return {
type: "textord",
text: " ",
mode: "math"
};
}
}
function parseCD(parser) {
var parsedRows = [];
parser.gullet.beginGroup();
parser.gullet.macros.set("\\cr", "\\\\\\relax");
parser.gullet.beginGroup();
while (true) {
parsedRows.push(parser.parseExpression(false, "\\\\"));
parser.gullet.endGroup();
parser.gullet.beginGroup();
var next = parser.fetch().text;
if (next === "&" || next === "\\\\") {
parser.consume();
} else if (next === "\\end") {
if (parsedRows[parsedRows.length - 1].length === 0) {
parsedRows.pop();
}
break;
} else {
throw new ParseError("Expected \\\\ or \\cr or \\end", parser.nextToken);
}
}
var row = [];
var body = [row];
for (var i = 0; i < parsedRows.length; i++) {
var rowNodes = parsedRows[i];
var cell = newCell();
for (var j = 0; j < rowNodes.length; j++) {
if (!isStartOfArrow(rowNodes[j])) {
cell.body.push(rowNodes[j]);
} else {
row.push(cell);
j += 1;
var arrowChar = assertSymbolNodeType(rowNodes[j]).text;
var labels = new Array(2);
labels[0] = {
type: "ordgroup",
mode: "math",
body: []
};
labels[1] = {
type: "ordgroup",
mode: "math",
body: []
};
if ("=|.".includes(arrowChar)) ;
else if ("<>AV".includes(arrowChar)) {
for (var labelNum = 0; labelNum < 2; labelNum++) {
var inLabel = true;
for (var k = j + 1; k < rowNodes.length; k++) {
if (isLabelEnd(rowNodes[k], arrowChar)) {
inLabel = false;
j = k;
break;
}
if (isStartOfArrow(rowNodes[k])) {
throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[k]);
}
labels[labelNum].body.push(rowNodes[k]);
}
if (inLabel) {
throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[j]);
}
}
} else {
throw new ParseError('Expected one of "<>AV=|." after @', rowNodes[j]);
}
var arrow = cdArrow(arrowChar, labels, parser);
var wrappedArrow = {
type: "styling",
body: [arrow],
mode: "math",
style: "display"
// CD is always displaystyle.
};
row.push(wrappedArrow);
cell = newCell();
}
}
if (i % 2 === 0) {
row.push(cell);
} else {
row.shift();
}
row = [];
body.push(row);
}
parser.gullet.endGroup();
parser.gullet.endGroup();
var cols = new Array(body[0].length).fill({
type: "align",
align: "c",
pregap: 0.25,
// CD package sets \enskip between columns.
postgap: 0.25
// So pre and post each get half an \enskip, i.e. 0.25em.
});
return {
type: "array",
mode: "math",
body,
arraystretch: 1,
addJot: true,
rowGaps: [null],
cols,
colSeparationType: "CD",
hLinesBeforeRow: new Array(body.length + 1).fill([])
};
}
function checkDelimiter(delim, context) {
var symDelim = checkSymbolNodeType(delim);
if (symDelim && delimiters.has(symDelim.text)) {
return symDelim;
} else if (symDelim) {
throw new ParseError("Invalid delimiter '" + symDelim.text + "' after '" + context.funcName + "'", delim);
} else {
throw new ParseError("Invalid delimiter type '" + delim.type + "'", delim);
}
}
function assertParsed(group) {
if (!group.body) {
throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");
}
}
function defineEnvironment(_ref) {
var {
type,
names,
props,
handler,
htmlBuilder: htmlBuilder3,
mathmlBuilder: mathmlBuilder3
} = _ref;
var data = {
type,
numArgs: props.numArgs || 0,
allowedInText: false,
numOptionalArgs: 0,
handler
};
for (var i = 0; i < names.length; ++i) {
_environments[names[i]] = data;
}
if (htmlBuilder3) {
_htmlGroupBuilders[type] = htmlBuilder3;
}
if (mathmlBuilder3) {
_mathmlGroupBuilders[type] = mathmlBuilder3;
}
}
function defineMacro(name, body) {
_macros[name] = body;
}
function getHLines(parser) {
var hlineInfo = [];
parser.consumeSpaces();
var nxt = parser.fetch().text;
if (nxt === "\\relax") {
parser.consume();
parser.consumeSpaces();
nxt = parser.fetch().text;
}
while (nxt === "\\hline" || nxt === "\\hdashline") {
parser.consume();
hlineInfo.push(nxt === "\\hdashline");
parser.consumeSpaces();
nxt = parser.fetch().text;
}
return hlineInfo;
}
function getAutoTag(name) {
if (!name.includes("ed")) {
return !name.includes("*");
}
}
function parseArray(parser, _ref, style) {
var {
hskipBeforeAndAfter,
addJot,
cols,
arraystretch,
colSeparationType,
autoTag,
singleRow,
emptySingleRow,
maxNumCols,
leqno
} = _ref;
parser.gullet.beginGroup();
if (!singleRow) {
parser.gullet.macros.set("\\cr", "\\\\\\relax");
}
if (!arraystretch) {
var stretch = parser.gullet.expandMacroAsText("\\arraystretch");
if (stretch == null) {
arraystretch = 1;
} else {
arraystretch = parseFloat(stretch);
if (!arraystretch || arraystretch < 0) {
throw new ParseError("Invalid \\arraystretch: " + stretch);
}
}
}
parser.gullet.beginGroup();
var row = [];
var body = [row];
var rowGaps = [];
var hLinesBeforeRow = [];
var tags = autoTag != null ? [] : void 0;
function beginRow() {
if (autoTag) {
parser.gullet.macros.set("\\@eqnsw", "1", true);
}
}
function endRow() {
if (tags) {
if (parser.gullet.macros.get("\\df@tag")) {
tags.push(parser.subparse([new Token("\\df@tag")]));
parser.gullet.macros.set("\\df@tag", void 0, true);
} else {
tags.push(Boolean(autoTag) && parser.gullet.macros.get("\\@eqnsw") === "1");
}
}
}
beginRow();
hLinesBeforeRow.push(getHLines(parser));
while (true) {
var cellBody = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
parser.gullet.endGroup();
parser.gullet.beginGroup();
var cell = {
type: "ordgroup",
mode: parser.mode,
body: cellBody
};
if (style) {
cell = {
type: "styling",
mode: parser.mode,
style,
body: [cell]
};
}
row.push(cell);
var next = parser.fetch().text;
if (next === "&") {
if (maxNumCols && row.length === maxNumCols) {
if (singleRow || colSeparationType) {
throw new ParseError("Too many tab characters: &", parser.nextToken);
} else {
parser.settings.reportNonstrict("textEnv", "Too few columns specified in the {array} column argument.");
}
}
parser.consume();
} else if (next === "\\end") {
endRow();
if (row.length === 1 && cell.type === "styling" && cell.body.length === 1 && cell.body[0].type === "ordgroup" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) {
body.pop();
}
if (hLinesBeforeRow.length < body.length + 1) {
hLinesBeforeRow.push([]);
}
break;
} else if (next === "\\\\") {
parser.consume();
var size = void 0;
if (parser.gullet.future().text !== " ") {
size = parser.parseSizeGroup(true);
}
rowGaps.push(size ? size.value : null);
endRow();
hLinesBeforeRow.push(getHLines(parser));
row = [];
body.push(row);
beginRow();
} else {
throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken);
}
}
parser.gullet.endGroup();
parser.gullet.endGroup();
return {
type: "array",
mode: parser.mode,
addJot,
arraystretch,
body,
cols,
rowGaps,
hskipBeforeAndAfter,
hLinesBeforeRow,
colSeparationType,
tags,
leqno
};
}
function dCellStyle(envName) {
if (envName.slice(0, 1) === "d") {
return "display";
} else {
return "text";
}
}
function sizingGroup(value, options, baseOptions) {
var inner2 = buildExpression$1(value, options, false);
var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier;
for (var i = 0; i < inner2.length; i++) {
var pos = inner2[i].classes.indexOf("sizing");
if (pos < 0) {
Array.prototype.push.apply(inner2[i].classes, options.sizingClasses(baseOptions));
} else if (inner2[i].classes[pos + 1] === "reset-size" + options.size) {
inner2[i].classes[pos + 1] = "reset-size" + baseOptions.size;
}
inner2[i].height *= multiplier;
inner2[i].depth *= multiplier;
}
return makeFragment(inner2);
}
var ParseError, uppercase, hyphenate, ESCAPE_LOOKUP, ESCAPE_REGEX, escape, getBaseElem, characterNodesTypes, isCharacterBox, protocolFromUrl, SETTINGS_SCHEMA, Settings, Style, D, Dc, T, Tc, S, Sc, SS, SSc, styles, sup, sub, fracNum, fracDen, cramp, text$1, Style$1, scriptData, allBlocks, hLinePad, sqrtMain, sqrtSize1, sqrtSize2, sqrtSize3, sqrtSize4, phasePath, sqrtTall, sqrtPath, innerPath, path, tallDelim, DocumentFragment, ptPerUnit, relativeUnit, validUnit, calculateSize, makeEm, createClass, initNode, toNode, invalidAttributeNameRegex, toMarkup, Span, Anchor, Img, iCombinations, SymbolNode, SvgNode, PathNode, LineNode, hasHtmlDomChildren, fontMetricsData, sigmasAndXis, extraCharacterMap, fontMetricsBySizeIndex, ATOMS, NON_ATOMS, symbols, math, text, main, ams, accent, bin, close, inner, mathord, op, open, punct, rel, spacing, textord, ligatures, mathTextSymbols, ch, i, textSymbols, _ch, _i, letters, _ch2, _i2, wideChar, _ch3, _i3, _ch4, _i4, extraLatin, _ch5, _i5, wideLatinLetterData, wideNumeralData, wideCharacterFont, lookupSymbol, makeSymbol, mathsym, boldsymbol, makeOrd, canCombine, tryCombineChars, sizeElementFromChildren, makeSpan, makeSvgSpan, makeLineSpan, makeAnchor, makeFragment, wrapFragment, getVListChildrenAndDepth, makeVList, makeGlue, retrieveTextFontName, fontMap, svgData, staticSvg, thinspace, mediumspace, thickspace, spacings, tightSpacings, _functions, _htmlGroupBuilders, _mathmlGroupBuilders, normalizeArgument, ordargument, binLeftCanceller, binRightCanceller, styleMap$1, DomEnum, buildExpression$1, _traverseNonSpaceNodes, checkPartialGroup, _getOutermostNode, getTypeOfDomTree, makeNullDelimiter, buildGroup$1, MathNode, TextNode, SpaceNode, noVariantSymbols, rowLikeTypes, makeText, makeRow, getVariant, buildExpression2, buildExpressionRow, buildGroup2, sizeStyleMap, sizeMultipliers, sizeAtStyle, Options, optionsFromSettings, displayWrap, buildTree, buildHTMLTree, stretchyCodePoint, stretchyMathML, katexImagesData, wideAccentLabels, stretchySvg, stretchyEnclose, getBaseSymbol, htmlBuilder$a, mathmlBuilder$9, NON_STRETCHY_ACCENT_REGEX, paddedNode, binrelClass, cdArrowFunctionName, newCell, isStartOfArrow, isLabelEnd, htmlBuilder$8, mathmlBuilder$7, globalMap, checkControlSequence, getRHS, letCommand, getMetrics, styleWrap, centerSpan, makeSmallDelim, mathrmSize, makeLargeDelim, makeGlyphSpan, makeInner, lapInEms, lap, verts, doubleVerts, makeStackedDelim, vbPad, emPad, sqrtSvg, makeSqrtImage, stackLargeDelimiters, stackAlwaysDelimiters, stackNeverDelimiters, sizeToMaxHeight, makeSizedDelim, stackNeverDelimiterSequence, stackAlwaysDelimiterSequence, stackLargeDelimiterSequence, delimTypeToFont, traverseSequence, makeCustomSizedDelim, makeLeftRightDelim, delimiterSizes, delimiters, htmlBuilder$7, mathmlBuilder$6, _environments, _macros, SourceLocation, Token, validateAmsEnvironmentContext, gatherEnvironments, htmlBuilder$6, alignMap, mathmlBuilder$5, alignedHandler, environments, htmlBuilder$5, mathmlBuilder$4, fontAliases, htmlBuilder$4, mathmlBuilder$3, wrapWithStyle, stylArray, delimFromValue, htmlBuilder$3, mathmlBuilder$2, sizeData, chooseMathStyle, assembleSupSub, noSuccessor, htmlBuilder$2, mathmlBuilder$1, singleCharBigOps, singleCharIntegrals, htmlBuilder$1, mathmlBuilder2, sizeFuncs, htmlBuilder2, styleMap, htmlBuilderDelegate, defaultVariant, cssSpace, regularSpace, pad, textFontFamilies, textFontWeights, textFontShapes, optionsWithFont, makeVerb, functions, spaceRegexString, controlWordRegexString, controlSymbolRegexString, controlWordWhitespaceRegexString, controlSpaceRegexString, combiningDiacriticalMarkString, combiningDiacriticalMarksEndRegex, tokenRegexString, Lexer, Namespace, macros, digitToNumber, newcommand, dotsByToken, dotsbGroups, spaceAfterDots, latexRaiseA, braketHelper, implicitCommands, MacroExpander, unicodeSubRegEx, uSubsAndSups, unicodeAccents, unicodeSymbols, Parser, parseTree, render, renderToString, generateParseTree, renderError, renderToDomTree, renderToHTMLTree, version, __domTree, katex;
var init_katex = __esm({
"node_modules/katex/dist/katex.mjs"() {
ParseError = class _ParseError extends Error {
// Error start position based on passed-in Token or ParseNode.
// Length of affected text based on passed-in Token or ParseNode.
// The underlying error message without any context added.
constructor(message, token) {
var error = "KaTeX parse error: " + message;
var start;
var end;
var loc = token && token.loc;
if (loc && loc.start <= loc.end) {
var input = loc.lexer.input;
start = loc.start;
end = loc.end;
if (start === input.length) {
error += " at end of input: ";
} else {
error += " at position " + (start + 1) + ": ";
}
var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332");
var left;
if (start > 15) {
left = "\u2026" + input.slice(start - 15, start);
} else {
left = input.slice(0, start);
}
var right;
if (end + 15 < input.length) {
right = input.slice(end, end + 15) + "\u2026";
} else {
right = input.slice(end);
}
error += left + underlined + right;
}
super(error);
this.name = "ParseError";
Object.setPrototypeOf(this, _ParseError.prototype);
this.position = start;
if (start != null && end != null) {
this.length = end - start;
}
this.rawMessage = message;
}
};
uppercase = /([A-Z])/g;
hyphenate = (str) => str.replace(uppercase, "-$1").toLowerCase();
ESCAPE_LOOKUP = {
"&": "&",
">": ">",
"<": "<",
'"': """,
"'": "'"
};
ESCAPE_REGEX = /[&><"']/g;
escape = (text2) => String(text2).replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
getBaseElem = (group) => {
if (group.type === "ordgroup") {
if (group.body.length === 1) {
return getBaseElem(group.body[0]);
} else {
return group;
}
} else if (group.type === "color") {
if (group.body.length === 1) {
return getBaseElem(group.body[0]);
} else {
return group;
}
} else if (group.type === "font") {
return getBaseElem(group.body);
} else {
return group;
}
};
characterNodesTypes = /* @__PURE__ */ new Set(["mathord", "textord", "atom"]);
isCharacterBox = (group) => characterNodesTypes.has(getBaseElem(group).type);
protocolFromUrl = (url) => {
var protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(url);
if (!protocol) {
return "_relative";
}
if (protocol[2] !== ":") {
return null;
}
if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(protocol[1])) {
return null;
}
return protocol[1].toLowerCase();
};
SETTINGS_SCHEMA = {
displayMode: {
type: "boolean",
description: "Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",
cli: "-d, --display-mode"
},
output: {
type: {
enum: ["htmlAndMathml", "html", "mathml"]
},
description: "Determines the markup language of the output.",
cli: "-F, --format <type>"
},
leqno: {
type: "boolean",
description: "Render display math in leqno style (left-justified tags)."
},
fleqn: {
type: "boolean",
description: "Render display math flush left."
},
throwOnError: {
type: "boolean",
default: true,
cli: "-t, --no-throw-on-error",
cliDescription: "Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."
},
errorColor: {
type: "string",
default: "#cc0000",
cli: "-c, --error-color <color>",
cliDescription: "A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",
cliProcessor: (color) => "#" + color
},
macros: {
type: "object",
cli: "-m, --macro <def>",
cliDescription: "Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",
cliDefault: [],
cliProcessor: (def, defs) => {
defs.push(def);
return defs;
}
},
minRuleThickness: {
type: "number",
description: "Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",
processor: (t) => Math.max(0, t),
cli: "--min-rule-thickness <size>",
cliProcessor: parseFloat
},
colorIsTextColor: {
type: "boolean",
description: "Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",
cli: "-b, --color-is-text-color"
},
strict: {
type: [{
enum: ["warn", "ignore", "error"]
}, "boolean", "function"],
description: "Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",
cli: "-S, --strict",
cliDefault: false
},
trust: {
type: ["boolean", "function"],
description: "Trust the input, enabling all HTML features such as \\url.",
cli: "-T, --trust"
},
maxSize: {
type: "number",
default: Infinity,
description: "If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",
processor: (s) => Math.max(0, s),
cli: "-s, --max-size <n>",
cliProcessor: parseInt
},
maxExpand: {
type: "number",
default: 1e3,
description: "Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",
processor: (n) => Math.max(0, n),
cli: "-e, --max-expand <n>",
cliProcessor: (n) => n === "Infinity" ? Infinity : parseInt(n)
},
globalGroup: {
type: "boolean",
cli: false
}
};
Settings = class {
constructor(options) {
if (options === void 0) {
options = {};
}
options = options || {};
for (var prop of Object.keys(SETTINGS_SCHEMA)) {
var schema = SETTINGS_SCHEMA[prop];
var optionValue = options[prop];
this[prop] = optionValue !== void 0 ? schema.processor ? schema.processor(optionValue) : optionValue : getDefaultValue(schema);
}
}
/**
* Report nonstrict (non-LaTeX-compatible) input.
* Can safely not be called if `this.strict` is false in JavaScript.
*/
reportNonstrict(errorCode, errorMsg, token) {
var strict = this.strict;
if (typeof strict === "function") {
strict = strict(errorCode, errorMsg, token);
}
if (!strict || strict === "ignore") {
return;
} else if (strict === true || strict === "error") {
throw new ParseError("LaTeX-incompatible input and strict mode is set to 'error': " + (errorMsg + " [" + errorCode + "]"), token);
} else if (strict === "warn") {
typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]"));
} else {
typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]"));
}
}
/**
* Check whether to apply strict (LaTeX-adhering) behavior for unusual
* input (like `\\`). Unlike `nonstrict`, will not throw an error;
* instead, "error" translates to a return value of `true`, while "ignore"
* translates to a return value of `false`. May still print a warning:
* "warn" prints a warning and returns `false`.
* This is for the second category of `errorCode`s listed in the README.
*/
useStrictBehavior(errorCode, errorMsg, token) {
var strict = this.strict;
if (typeof strict === "function") {
try {
strict = strict(errorCode, errorMsg, token);
} catch (error) {
strict = "error";
}
}
if (!strict || strict === "ignore") {
return false;
} else if (strict === true || strict === "error") {
return true;
} else if (strict === "warn") {
typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]"));
return false;
} else {
typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]"));
return false;
}
}
/**
* Check whether to test potentially dangerous input, and return
* `true` (trusted) or `false` (untrusted). The sole argument `context`
* should be an object with `command` field specifying the relevant LaTeX
* command (as a string starting with `\`), and any other arguments, etc.
* If `context` has a `url` field, a `protocol` field will automatically
* get added by this function (changing the specified object).
*/
isTrusted(context) {
if ("url" in context && context.url && !context.protocol) {
var protocol = protocolFromUrl(context.url);
if (protocol == null) {
return false;
}
context.protocol = protocol;
}
var trust = typeof this.trust === "function" ? this.trust(context) : this.trust;
return Boolean(trust);
}
};
Style = class {
constructor(id, size, cramped) {
this.id = id;
this.size = size;
this.cramped = cramped;
}
/**
* Get the style of a superscript given a base in the current style.
*/
sup() {
return styles[sup[this.id]];
}
/**
* Get the style of a subscript given a base in the current style.
*/
sub() {
return styles[sub[this.id]];
}
/**
* Get the style of a fraction numerator given the fraction in the current
* style.
*/
fracNum() {
return styles[fracNum[this.id]];
}
/**
* Get the style of a fraction denominator given the fraction in the current
* style.
*/
fracDen() {
return styles[fracDen[this.id]];
}
/**
* Get the cramped version of a style (in particular, cramping a cramped style
* doesn't change the style).
*/
cramp() {
return styles[cramp[this.id]];
}
/**
* Get a text or display version of this style.
*/
text() {
return styles[text$1[this.id]];
}
/**
* Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle)
*/
isTight() {
return this.size >= 2;
}
};
D = 0;
Dc = 1;
T = 2;
Tc = 3;
S = 4;
Sc = 5;
SS = 6;
SSc = 7;
styles = [new Style(D, 0, false), new Style(Dc, 0, true), new Style(T, 1, false), new Style(Tc, 1, true), new Style(S, 2, false), new Style(Sc, 2, true), new Style(SS, 3, false), new Style(SSc, 3, true)];
sup = [S, Sc, S, Sc, SS, SSc, SS, SSc];
sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc];
fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc];
fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc];
cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
text$1 = [D, Dc, T, Tc, T, Tc, T, Tc];
Style$1 = {
DISPLAY: styles[D],
TEXT: styles[T],
SCRIPT: styles[S],
SCRIPTSCRIPT: styles[SS]
};
scriptData = [{
// Latin characters beyond the Latin-1 characters we have metrics for.
// Needed for Czech, Hungarian and Turkish text, for example.
name: "latin",
blocks: [
[256, 591],
// Latin Extended-A and Latin Extended-B
[768, 879]
// Combining Diacritical marks
]
}, {
// The Cyrillic script used by Russian and related languages.
// A Cyrillic subset used to be supported as explicitly defined
// symbols in symbols.js
name: "cyrillic",
blocks: [[1024, 1279]]
}, {
// Armenian
name: "armenian",
blocks: [[1328, 1423]]
}, {
// The Brahmic scripts of South and Southeast Asia
// Devanagari (0900–097F)
// Bengali (0980–09FF)
// Gurmukhi (0A00–0A7F)
// Gujarati (0A80–0AFF)
// Oriya (0B00–0B7F)
// Tamil (0B80–0BFF)
// Telugu (0C00–0C7F)
// Kannada (0C80–0CFF)
// Malayalam (0D00–0D7F)
// Sinhala (0D80–0DFF)
// Thai (0E00–0E7F)
// Lao (0E80–0EFF)
// Tibetan (0F00–0FFF)
// Myanmar (1000–109F)
name: "brahmic",
blocks: [[2304, 4255]]
}, {
name: "georgian",
blocks: [[4256, 4351]]
}, {
// Chinese and Japanese.
// The "k" in cjk is for Korean, but we've separated Korean out
name: "cjk",
blocks: [
[12288, 12543],
// CJK symbols and punctuation, Hiragana, Katakana
[19968, 40879],
// CJK ideograms
[65280, 65376]
// Fullwidth punctuation
// TODO: add halfwidth Katakana and Romanji glyphs
]
}, {
// Korean
name: "hangul",
blocks: [[44032, 55215]]
}];
allBlocks = [];
scriptData.forEach((s) => s.blocks.forEach((b) => allBlocks.push(...b)));
hLinePad = 80;
sqrtMain = function sqrtMain2(extraVinculum, hLinePad2) {
return "M95," + (622 + extraVinculum + hLinePad2) + "\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl" + extraVinculum / 2.075 + " -" + extraVinculum + "\nc5.3,-9.3,12,-14,20,-14\nH400000v" + (40 + extraVinculum) + "H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM" + (834 + extraVinculum) + " " + hLinePad2 + "h400000v" + (40 + extraVinculum) + "h-400000z";
};
sqrtSize1 = function sqrtSize12(extraVinculum, hLinePad2) {
return "M263," + (601 + extraVinculum + hLinePad2) + "c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl" + extraVinculum / 2.084 + " -" + extraVinculum + "\nc4.7,-7.3,11,-11,19,-11\nH40000v" + (40 + extraVinculum) + "H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM" + (1001 + extraVinculum) + " " + hLinePad2 + "h400000v" + (40 + extraVinculum) + "h-400000z";
};
sqrtSize2 = function sqrtSize22(extraVinculum, hLinePad2) {
return "M983 " + (10 + extraVinculum + hLinePad2) + "\nl" + extraVinculum / 3.13 + " -" + extraVinculum + "\nc4,-6.7,10,-10,18,-10 H400000v" + (40 + extraVinculum) + "\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM" + (1001 + extraVinculum) + " " + hLinePad2 + "h400000v" + (40 + extraVinculum) + "h-400000z";
};
sqrtSize3 = function sqrtSize32(extraVinculum, hLinePad2) {
return "M424," + (2398 + extraVinculum + hLinePad2) + "\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl" + extraVinculum / 4.223 + " -" + extraVinculum + "c4,-6.7,10,-10,18,-10 H400000\nv" + (40 + extraVinculum) + "H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M" + (1001 + extraVinculum) + " " + hLinePad2 + "\nh400000v" + (40 + extraVinculum) + "h-400000z";
};
sqrtSize4 = function sqrtSize42(extraVinculum, hLinePad2) {
return "M473," + (2713 + extraVinculum + hLinePad2) + "\nc339.3,-1799.3,509.3,-2700,510,-2702 l" + extraVinculum / 5.298 + " -" + extraVinculum + "\nc3.3,-7.3,9.3,-11,18,-11 H400000v" + (40 + extraVinculum) + "H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM" + (1001 + extraVinculum) + " " + hLinePad2 + "h400000v" + (40 + extraVinculum) + "H1017.7z";
};
phasePath = function phasePath2(y) {
var x = y / 2;
return "M400000 " + y + " H0 L" + x + " 0 l65 45 L145 " + (y - 80) + " H400000z";
};
sqrtTall = function sqrtTall2(extraVinculum, hLinePad2, viewBoxHeight) {
var vertSegment = viewBoxHeight - 54 - hLinePad2 - extraVinculum;
return "M702 " + (extraVinculum + hLinePad2) + "H400000" + (40 + extraVinculum) + "\nH742v" + vertSegment + "l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 " + hLinePad2 + "H400000v" + (40 + extraVinculum) + "H742z";
};
sqrtPath = function sqrtPath2(size, extraVinculum, viewBoxHeight) {
extraVinculum = 1e3 * extraVinculum;
var path2 = "";
switch (size) {
case "sqrtMain":
path2 = sqrtMain(extraVinculum, hLinePad);
break;
case "sqrtSize1":
path2 = sqrtSize1(extraVinculum, hLinePad);
break;
case "sqrtSize2":
path2 = sqrtSize2(extraVinculum, hLinePad);
break;
case "sqrtSize3":
path2 = sqrtSize3(extraVinculum, hLinePad);
break;
case "sqrtSize4":
path2 = sqrtSize4(extraVinculum, hLinePad);
break;
case "sqrtTall":
path2 = sqrtTall(extraVinculum, hLinePad, viewBoxHeight);
}
return path2;
};
innerPath = function innerPath2(name, height) {
switch (name) {
case "\u239C":
return "M291 0 H417 V" + height + " H291z M291 0 H417 V" + height + " H291z";
case "\u2223":
return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z";
case "\u2225":
return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z" + ("M367 0 H410 V" + height + " H367z M367 0 H410 V" + height + " H367z");
case "\u239F":
return "M457 0 H583 V" + height + " H457z M457 0 H583 V" + height + " H457z";
case "\u23A2":
return "M319 0 H403 V" + height + " H319z M319 0 H403 V" + height + " H319z";
case "\u23A5":
return "M263 0 H347 V" + height + " H263z M263 0 H347 V" + height + " H263z";
case "\u23AA":
return "M384 0 H504 V" + height + " H384z M384 0 H504 V" + height + " H384z";
case "\u23D0":
return "M312 0 H355 V" + height + " H312z M312 0 H355 V" + height + " H312z";
case "\u2016":
return "M257 0 H300 V" + height + " H257z M257 0 H300 V" + height + " H257z" + ("M478 0 H521 V" + height + " H478z M478 0 H521 V" + height + " H478z");
default:
return "";
}
};
path = {
// The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main
doubleleftarrow: "M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3